Page 1 sur 1

Min/Max algo pour clone de Puyo-Puyo

Publié : mar. 06/nov./2018 20:40
par Fig
Ce n'est pas un jeu abouti, je voulais juste faire un test de l'algo Min-max.
En mettant joueur0=#Human ligne 6, vous pourrez jouer... Mais sans ralentir l'Ia, je doute que ce soit jouable très longtemps.
(fleches gauche/droite pour bouger, bas pour le descendre rapidement, haut pour tourner la pièce)
En mettant joueur1=#human ligne 6, vous pourrez jouer à deux (touche C F V et espace).

Pas de GameOver de toute façon.
[Escape] pour quitter.
[P] pour pauser le jeu.

Je cherche à améliorer la profondeur de réflexion de l'IA mais quelque chose ne fonctionne pas, quoique ça ne bug pas.
J'y travaille.

En état c'est sympathique de regarder l'IA jouer contre elle-même... :idea:

Code : Tout sélectionner

#TileSize=40 ;taille d'un puyo, l'écran s'adapte à nos vieux yeux.
Global DeepMax.i=1 ;profondeur d'analyse (max 2 ou 3 mais ça ne fonctionne pas encore:/)
speed.i=500 ;delay pour la descente d'une pièce
#WaitKey=150 ;delay entre deux touches
#Human=0:#IA=1
joueur0=#IA ;0=humain 1=IA
joueur1=#IA ;0=humain 1=IA


#nbColor=5 ;nombre de type de puyo
#gui=#TileSize*5
#Void=6 ;black
#OjamaColor=5;grey

#Ojama=$2b251c ;bad puyo color
#Purple=$940b94
#Orange=$0396eb
#Redish=$281bd0
#Greenish=$157325
#blueish=$734c15

#X=(#TileSize*12)+#gui:#Y=#TileSize*12 ;screen size
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse()=0: MessageRequester("Error", "Can't open the sprite system", 0): End: EndIf
If OpenWindow(0, 0, 0, #X, #Y, "Puyo-Puyo", #PB_Window_SystemMenu) = 0: MessageRequester("Error", "Can't open windowed screen!", 0): EndIf
If OpenWindowedScreen(WindowID(0), 0, 0, #X, #Y) = 0: MessageRequester("Error", "Can't open windowed screen!", 0): EndIf
Structure player
    Timer.q 
    WaitKey.q
    Speed.i 
    Bloc.i 
    Void.i 
    moved.i
    Ojama.i
    NumDuet.i
    NumOjama.i
    score.i
    Player.i ;human=0 Ia=1
    StartIa.i
    Eval.i
    Array keyB.i(3)
    List Command.i()
EndStructure
Structure game
    color.i
    done.i
EndStructure
Structure xy
    x.i
    y.i
EndStructure
Structure n
    color1.i
    color2.i
EndStructure
Global Dim Game.game(5,11,1):For k=0 To 1:For j=0 To 11:For i=0 To 5:Game(i,j,k)\color=#Void:Next i:Next j:Next k
Global Dim color.i(#nbColor):For i=0 To #nbColor:Read color(i):Next i
Global Dim Duet.xy(1,1)
Global NewList Delete.point()
Global NewList NextDuet.n()
Global Dim Player.player(1)
For k=0 To 1:For i=0 To 3:Read Player(k)\keyB(i):Next i:Next k
Player(0)\Speed=speed:Player(1)\Speed=speed
Player(0)\Player=joueur0:Player(1)\Player=joueur1

Procedure Max(a.i,b.i)
    If a<b:a=b:EndIf
    ProcedureReturn a
EndProcedure

Procedure Min(a.i,b.i)
    If a>b:a=b:EndIf
    ProcedureReturn a
EndProcedure

Procedure Sum(x.i,y.i,Player,Array gam.game(3),List delet.point())
    If gam(x,y,Player)\done=1
        ProcedureReturn
    EndIf
    gam(x,y,Player)\done=1
    If gam(x,y,Player)\color=#Void Or gam(x,y,Player)\color=#OjamaColor
        ProcedureReturn
    EndIf
    If x<5 And gam(x,y,Player)\color=gam(x+1,y,Player)\color And gam(x+1,y,Player)\done=0
        sum(x+1,y,Player,gam(),delet())
    EndIf
    If x>0 And gam(x,y,Player)\color=gam(x-1,y,Player)\color And gam(x-1,y,Player)\done=0
        sum(x-1,y,Player,gam(),delet())
    EndIf
    If y<11 And gam(x,y,Player)\color=gam(x,y+1,Player)\color And gam(x,y+1,Player)\done=0
        sum(x,y+1,Player,gam(),delet())
    EndIf
    If y>0 And gam(x,y,Player)\color=gam(x,y-1,Player)\color And gam(x,y-1,Player)\done=0
        sum(x,y-1,Player,gam(),delet())
    EndIf
    AddElement(delet()):delet()\x=x:delet()\y=y
EndProcedure

Procedure CheckGame(Player.i,Array gam.game(3),Array P.player(1))
    NewList delet.point()
    Erase.i=0
    ;clear "done" in array
    For i=0 To 5
        For j=0 To 11
            gam(i,j,Player)\done=0 
        Next j
    Next i
    For j=0 To 11
        For i=0 To 5
            If gam(i,j,Player)\color=#Void Or gam(i,j,Player)\color=#OjamaColor:Continue:EndIf
            ClearList(delet())
            Sum(i,j,Player,gam(),delet())
            P(Player)\Eval+Pow(ListSize(delet()),2)
            If ListSize(delet())>3
                P(Player!1)\NumOjama+ListSize(delet())-3
                Erase=1
                P(Player)\score+ListSize(delet())
                ForEach delet()
                    gam(delet()\x,delet()\y,Player)\color=#Void
                    ;right
                    If delet()\x<5 And gam(delet()\x+1,delet()\y,Player)\color=#OjamaColor
                        gam(delet()\x+1,delet()\y,Player)\color=#Void
                    EndIf
                    ;left
                    If delet()\x>0 And gam(delet()\x-1,delet()\y,Player)\color=#OjamaColor
                        gam(delet()\x-1,delet()\y,Player)\color=#Void
                    EndIf
                    ;Up
                    If delet()\y>0 And gam(delet()\x,delet()\y-1,Player)\color=#OjamaColor
                        gam(delet()\x,delet()\y-1,Player)\color=#Void
                    EndIf
                    ;Down
                    If delet()\y<11 And gam(delet()\x,delet()\y+1,Player)\color=#OjamaColor
                        gam(delet()\x,delet()\y+1,Player)\color=#Void
                    EndIf
                Next
            EndIf
        Next i
    Next j
    ProcedureReturn Erase
EndProcedure

Procedure NewDuet(Player.i,Array gam.game(3),Array duo.xy(2),*numduet.integer)
    SelectElement(NextDuet(),*NumDuet\i)
    ;avance dans la liste...
    *NumDuet\i+1
    gam(2,0,Player)\color=NextDuet()\color1
    gam(2,1,Player)\color=NextDuet()\color2
    Duo(0,Player)\x=2
    Duo(0,Player)\y=0
    Duo(1,Player)\x=2
    Duo(1,Player)\y=1
    ;génère un nouveau duo au bout de la liste
        LastElement(NextDuet())
        AddElement(NextDuet())
        NextDuet()\color1=Random(#nbColor-1)
        NextDuet()\color2=Random(#nbColor-1)
EndProcedure

Procedure GravityDuet(Player.i,Array gam.game(3),Array duo.xy(2))
    bloc.i=0
    max.i=0:min.i=1
    If Duo(0,Player)\y<Duo(1,Player)\y
        max=1
        min=0
    EndIf  
    For k=0 To 1
        ;fait descendre le 1/2 puyo
        ;horizontal
        If Duo(0,Player)\x<>Duo(1,Player)\x
            If Duo(k,Player)\y=11 Or gam(Duo(k,Player)\x,Duo(k,Player)\y+1,Player)\color<>#Void
                bloc+1
                Continue
            EndIf    
            Swap gam(Duo(k,Player)\x,Duo(k,Player)\y,Player)\color,gam(Duo(k,Player)\x,Duo(k,Player)\y+1,Player)\color
            Duo(k,Player)\y+1
            ;vertical
        ElseIf Duo(min,Player)\y<Duo(max,Player)\y
            If Duo(max,Player)\y=11 Or gam(Duo(max,Player)\x,Duo(max,Player)\y+1,Player)\color<>#Void
                bloc=2
                Break
            EndIf
            Swap gam(Duo(max,Player)\x,Duo(max,Player)\y,Player)\color,gam(Duo(max,Player)\x,Duo(max,Player)\y+1,Player)\color
            Swap gam(Duo(min,Player)\x,Duo(min,Player)\y,Player)\color,gam(Duo(min,Player)\x,Duo(min,Player)\y+1,Player)\color
            Duo(0,Player)\y+1
            Duo(1,Player)\y+1
            Break
        EndIf    
    Next
    ProcedureReturn bloc
EndProcedure

Procedure GlobalGravity(Player.i,Array gam.game(3),Array duo.xy(2))
    ;fait descendre le reste du jeu
    moved.i=0
    For j=10 To 0 Step -1
        For i=0 To 5
            If gam(i,j,Player)\color=#Void Or (i=duo(0,player)\x And y=duo(0,player)\y) Or (i=duo(1,player)\x And y=duo(1,player)\y)
                Continue
            EndIf
            If gam(i,j+1,Player)\color=#Void
                Swap gam(i,j,Player)\color,gam(i,j+1,Player)\color
                moved=1
            EndIf    
        Next i
    Next j
    ProcedureReturn moved
EndProcedure

Procedure AttaquePuyo(Player.i,Array gam.game(3),Array P.player(1))
    ojama.i=0
    If P(Player)\NumOjama>0
        ojama=1
        For i=1 To P(Player)\NumOjama
            If i=7:Break:EndIf
            gam(Random(5),0,player)\color=#OjamaColor
        Next i
        If P(Player)\NumOjama>6
            P(Player)\NumOjama-6
        Else
            P(Player)\NumOjama=0
        EndIf
    EndIf
    ProcedureReturn ojama
EndProcedure    

Procedure RunCommand(player.i,Array Gam.game(3),List command.i(), Array duo.xy(2),*speed.integer)
    k=player
    If ListSize(Command())
        LastElement(command())
            ;UP    (Rotate clockwise)
            If Command()=#PB_Key_Up
                ;horizontal, pivot à gauche
                If Duo(0,k)\x<Duo(1,k)\x
                    If Duo(0,k)\y<11 And gam(Duo(0,k)\x,Duo(0,k)\y+1,k)\color=#Void
                        Swap gam(Duo(1,k)\x,Duo(1,k)\y,k)\color,gam(Duo(0,k)\x,Duo(0,k)\y+1,k)\color
                        Duo(1,k)\x=Duo(0,k)\x
                        Duo(1,k)\y=Duo(0,k)\y+1
                    ElseIf Duo(0,k)\y>0 And gam(Duo(0,k)\x,Duo(0,k)\y-1,k)\color=#Void
                        Swap gam(Duo(0,k)\x,Duo(0,k)\y,k)\color,gam(Duo(0,k)\x,Duo(0,k)\y-1,k)\color
                        Swap gam(Duo(1,k)\x,Duo(1,k)\y,k)\color,gam(Duo(1,k)\x-1,Duo(1,k)\y,k)\color
                        Duo(0,k)\x=Duo(0,k)\x
                        Duo(0,k)\y=Duo(0,k)\y-1
                        Duo(1,k)\x=Duo(1,k)\x-1
                        Duo(1,k)\y=Duo(1,k)\y
                    EndIf
                    ;horizontal, pivot à droite
                ElseIf Duo(0,k)\x>Duo(1,k)\x
                    If Duo(0,k)\y>0 And gam(Duo(0,k)\x,Duo(0,k)\y-1,k)\color=#Void
                        Swap gam(Duo(1,k)\x,Duo(1,k)\y,k)\color,gam(Duo(0,k)\x,Duo(0,k)\y-1,k)\color
                        Duo(1,k)\x=Duo(0,k)\x
                        Duo(1,k)\y=Duo(0,k)\y-1
                    ElseIf Duo(0,k)\y<11 And gam(Duo(0,k)\x,Duo(0,k)\y+1,k)\color=#Void
                        Swap gam(Duo(0,k)\x,Duo(0,k)\y,k)\color,gam(Duo(0,k)\x,Duo(0,k)\y+1,k)\color
                        Swap gam(Duo(1,k)\x,Duo(1,k)\y,k)\color,gam(Duo(1,k)\x+1,Duo(1,k)\y,k)\color
                        Duo(0,k)\x=Duo(0,k)\x
                        Duo(0,k)\y=Duo(0,k)\y+1
                        Duo(1,k)\x=Duo(1,k)\x+1
                        Duo(1,k)\y=Duo(1,k)\y
                    EndIf
                    ;vertical, pivot en haut
                ElseIf Duo(0,k)\y<Duo(1,k)\y
                    If Duo(0,k)\x>0 And gam(Duo(0,k)\x-1,Duo(0,k)\y,k)\color=#Void
                        Swap gam(Duo(1,k)\x,Duo(1,k)\y,k)\color,gam(Duo(0,k)\x-1,Duo(0,k)\y,k)\color
                        Duo(1,k)\x=Duo(0,k)\x-1
                        Duo(1,k)\y=Duo(0,k)\y
                    ElseIf Duo(0,k)\x<5 And gam(Duo(0,k)\x+1,Duo(0,k)\y,k)\color=#Void
                        Swap gam(Duo(0,k)\x,Duo(0,k)\y,k)\color,gam(Duo(0,k)\x+1,Duo(0,k)\y,k)\color
                        Swap gam(Duo(1,k)\x,Duo(1,k)\y,k)\color,gam(Duo(1,k)\x,Duo(1,k)\y-1,k)\color
                        Duo(0,k)\x=Duo(0,k)\x+1
                        Duo(0,k)\y=Duo(0,k)\y
                        Duo(1,k)\x=Duo(1,k)\x
                        Duo(1,k)\y=Duo(1,k)\y-1
                    EndIf
                    ;vertical, pivot en bas
                ElseIf Duo(0,k)\y>Duo(1,k)\y
                    If Duo(0,k)\x<5 And gam(Duo(0,k)\x+1,Duo(0,k)\y,k)\color=#Void
                        Swap gam(Duo(1,k)\x,Duo(1,k)\y,k)\color,gam(Duo(0,k)\x+1,Duo(0,k)\y,k)\color
                        Duo(1,k)\x=Duo(0,k)\x+1
                        Duo(1,k)\y=Duo(0,k)\y
                    ElseIf Duo(0,k)\x>0 And gam(Duo(0,k)\x-1,Duo(0,k)\y,k)\color=#Void
                        Swap gam(Duo(0,k)\x,Duo(0,k)\y,k)\color,gam(Duo(0,k)\x-1,Duo(0,k)\y,k)\color
                        Swap gam(Duo(1,k)\x,Duo(1,k)\y,k)\color,gam(Duo(1,k)\x,Duo(1,k)\y+1,k)\color
                        Duo(0,k)\x=Duo(0,k)\x-1
                        Duo(0,k)\y=Duo(0,k)\y
                        Duo(1,k)\x=Duo(1,k)\x
                        Duo(1,k)\y=Duo(1,k)\y+1
                    EndIf            
                EndIf 
                DeleteElement(Command())
            
            ;Down (Fast or Slow)
            ElseIf Command()=#PB_Key_Down
                *Speed\i=0
                DeleteElement(Command())
            
            ;Move Left
            ElseIf Command()=#PB_Key_Left
                x1=min(Duo(0,k)\x,Duo(1,k)\x)
                x2=max(Duo(0,k)\x,Duo(1,k)\x)
                If x1>0 And gam(x1-1,Duo(0,k)\y,k)\color=#Void
                    Swap gam(x1,Duo(0,k)\y,k)\color,gam(x1-1,Duo(0,k)\y,k)\color
                    Swap gam(x2,Duo(1,k)\y,k)\color,gam(x2-1,Duo(1,k)\y,k)\color
                    Duo(0,k)\x-1
                    Duo(1,k)\x-1
                EndIf
                DeleteElement(Command())
            
            ;Move Right
            ElseIf Command()=#PB_Key_Right
                x1=min(Duo(0,k)\x,Duo(1,k)\x)
                x2=max(Duo(0,k)\x,Duo(1,k)\x)
                If x2<5 And gam(x2+1,Duo(0,k)\y,k)\color=#Void
                    Swap gam(x2,Duo(1,k)\y,k)\color,gam(x2+1,Duo(1,k)\y,k)\color
                    Swap gam(x1,Duo(0,k)\y,k)\color,gam(x1+1,Duo(0,k)\y,k)\color
                    Duo(0,k)\x+1
                    Duo(1,k)\x+1
                EndIf
                DeleteElement(Command())
            EndIf
        EndIf
EndProcedure    

Procedure IA_R(player.i,deep.i,Array gam.game(3), Array Duo.xy(2), Array EvalTest.i(2))
    deep+1
    Dim DuetTest.xy(1,1)
    Dim GameTest.game(5,11,1)
    Dim scoreTest.i(5,3)
    NewList com.i()
    Dim P.player(1)
    
        For pos=0 To 3
            For x=0 To 5
                ;initialise le jeu virtuel
                CopyArray(Gam(),GameTest())
                CopyArray(Duo(),DuetTest())
                ;met le duet le plus à gauche possible
                For i=0 To 5:AddElement(com()):com()=#PB_Key_Left:Runcommand(player,GameTest(),com(),duetTest(),@player(player)\speed):Next i
                ;avance le duo à droite, le plus proche possible de la coordonnée x
                For i=1 To x:AddElement(com()):com()=#PB_Key_Right:Runcommand(player,GameTest(),com(),duetTest(),@player(player)\speed):Next i
                ;tourne le duo dans la position voulue
                For i=1 To pos:AddElement(com()):com()=#PB_Key_Up:Runcommand(player,GameTest(),com(),duetTest(),@player(player)\speed):Next i
                
                ;on fait descendre le duo jusqu'en bas
                While GravityDuet(Player,GameTest(),DuetTest())<>2:Wend
                ;on fait des trous et on compte les points et l'évaluation
                P(player)\Eval=0
                While checkGame(Player,gameTest(),P())<>0
                    While globalGravity(player,gameTest(),DuetTest())<>0;on fait descendre tout le jeu pour remplir les trous
                    Wend
                Wend
                ;total des points et de l'évaluation du coup virtuellement joué
                scoreTest(x,pos)+P(player)\score
                EvalTest(x,pos)+P(player)\Eval
                Debug "Deep"+Str(deep)+"Eval "+Str(p(player)\Eval)+" evalTest("+Str(x)+","+Str(pos)+")="+Str(EvalTest(x,pos))
                ;On lance la récursion un échelon plus profond
                numduet.i=deep+player(player)\NumDuet-1
                NewDuet(player,GameTest(),DuetTest(),@numduet)
                If deep<DeepMax
                    IA_R(player, deep, GameTest(), DuetTest(), EvalTest())
                EndIf
            Next x
        Next pos
        Debug " "
EndProcedure

Procedure IA(player.i)
    Dim EvalTest.i(5,3)
    deep.i=0
    IA_R(player,deep,game(),Duet(),EvalTest())
    
        ;on cherche la colonne et la position avec la meilleur évaluation: c'est le meilleur coup possible à jouer.
        eval.i=0:max.i=6:maxPos.i=0
        For pos=0 To 3
            For i=0 To 5
                If EvalTest(i,pos)>=eval            
                    max=i
                    maxpos=pos
                    eval=EvalTest(i,pos)
                EndIf           
            Next i
        Next pos
        If max=6:max=Random(5):Debug "random":EndIf
        ClearList(player(player)\Command())
        ;met le duo le plus à gauche possible
        For i=0 To 5
            FirstElement(player(player)\Command())
            InsertElement(player(player)\Command())
            player(player)\Command()=#PB_Key_Left
        Next i
        ;avance le duo à droite, le plus proche possible de la coordonnée max
        For i=1 To max
            FirstElement(player(player)\Command())
            InsertElement(player(player)\Command())
            player(player)\Command()=#PB_Key_Right
        Next i
        ;tourne le duo dans la position voulue maxPos
        For i=1 To maxPos
            FirstElement(player(player)\Command())
            InsertElement(player(player)\Command())
            player(player)\Command()=#PB_Key_Up
        Next i  
        ;fait descendre la pièce rapidement
        For i=0 To 11
            FirstElement(player(player)\Command())
            InsertElement(player(player)\Command())
            player(player)\Command()=#PB_Key_Down
        Next i

EndProcedure

Procedure DisplayGame()
    For k=0 To 1
        ;display Gui
        SelectElement(NextDuet(),Player(k)\NumDuet)
        DisplayTransparentSprite(1,#TileSize*7+k*#TileSize*2,#TileSize*2,255,color(NextDuet()\color1))
        DisplayTransparentSprite(1,#TileSize*7+k*#TileSize*2,#TileSize*3,255,color(NextDuet()\color2))
        NextElement(NextDuet())
        ZoomSprite(1,#TileSize>>1,#TileSize>>1)
        DisplayTransparentSprite(1,#TileSize*7+k*#TileSize*2,#TileSize*6,255,color(NextDuet()\color1))
        DisplayTransparentSprite(1,#TileSize*7+k*#TileSize*2,#TileSize*6+#TileSize/2,255,color(NextDuet()\color2))
        ZoomSprite(1,#TileSize,#TileSize)
        
        ;text display
        StartDrawing(ScreenOutput())
        ;Ojama number awaiting
        DrawText(#TileSize*6+k*#TileSize*5-k*TextWidth(Str(player(k)\NumOjama)),#TileSize*10,Str(player(k)\NumOjama))
        ;Score
        DrawText(#TileSize*6+k*#TileSize*5-k*TextWidth(Str(player(k)\NumOjama)),#TileSize*8,Str(player(k)\score))
        StopDrawing()
        
        ;display game's elements
        For i=0 To 5
            For j=0 To 11
                If game(i,j,k)\color<>#Void
                    DisplayTransparentSprite(1,i*#TileSize+k*#TileSize*6+k*#gui,j*#TileSize,255,color(game(i,j,k)\color))
                    If Duet(0,k)\x=i And Duet(0,k)\y=j
                        DisplayTransparentSprite(2,i*#TileSize+k*#TileSize*6+k*#gui,j*#TileSize)
                    EndIf
                EndIf
            Next j
        Next i
    Next k
EndProcedure

;fond d'écran
CreateSprite(0,#x,#y)
StartDrawing(SpriteOutput(0))
Box(0,0,#x,#y,RGB(100,100,100)):For k=0 To 1:For j=0 To 11:For i=0 To 5:Box(i*#TileSize+1+k*#TileSize*6+k*#gui,j*#TileSize+1,#TileSize-2,#TileSize-2,RGB(120,120,120)):Next i:Next j:Next k
StopDrawing()
;goutte
CreateSprite(1,#TileSize,#TileSize)
StartDrawing(SpriteOutput(1))
Box(0,0,#TileSize,#TileSize,#White)
StopDrawing()
;pivot
CreateSprite(2,#TileSize,#TileSize)
StartDrawing(SpriteOutput(2))
Circle(#TileSize>>1,#TileSize>>1,#TileSize>>2,RGB(1,1,1))
StopDrawing()

;generate #deep future duets to come
For k=0 To DeepMax
    AddElement(NextDuet()):NextDuet()\color1=Random(#nbColor-1):NextDuet()\color2=Random(#nbColor-1)
Next k
NewDuet(0,game(),duet(),@player(0)\NumDuet)
NewDuet(1,game(),duet(),@player(1)\NumDuet)

Repeat
    Repeat
        Repeat
        Until WindowEvent()=0
        FlipBuffers()
        DisplaySprite(0,0,0)
        ExamineKeyboard()
        ExamineMouse()
        DisplayGame()
        If KeyboardReleased(#PB_Key_P):pause=1!pause:EndIf
    Until Pause=0
    ;{- Inputs commands Player 0 and 1
    For k=0 To 1
        Player(k)\Speed=speed
        ;si le joueur est humain
        If Player(k)\Player=0
            ;Up
            If KeyboardPushed(Player(k)\keyB(0)) And Player(k)\waitkey+#WaitKey<ElapsedMilliseconds()
                AddElement(player(k)\Command())
                player(k)\Command()=#PB_Key_Up
                Player(k)\waitkey=ElapsedMilliseconds()
            EndIf
            ;Down
            If KeyboardPushed(Player(k)\keyB(1))
                AddElement(player(k)\Command())
                player(k)\Command()=#PB_Key_Down
                Player(k)\waitkey=ElapsedMilliseconds()
            EndIf  
            ;Left
            If KeyboardPushed(Player(k)\keyB(2)) And Player(k)\waitkey+#WaitKey<ElapsedMilliseconds() 
                AddElement(player(k)\Command())
                player(k)\Command()=#PB_Key_Left
                Player(k)\waitkey=ElapsedMilliseconds()
            EndIf
            ;Right
            If KeyboardPushed(Player(k)\keyB(3)) And Player(k)\waitkey+#WaitKey<ElapsedMilliseconds()
                AddElement(player(k)\Command())
                player(k)\Command()=#PB_Key_Right
                Player(k)\waitkey=ElapsedMilliseconds()
            EndIf  
        ;Si le joueur est une IA
        ElseIf Player(k)\StartIa=1
            Player(k)\StartIa=0
            IA(k)
        EndIf    
    Next k
    ;}
    
    ;{- Execute les commandes
    For k=0 To 1
        If player(k)\Player=#IA And Player(k)\waitkey+#WaitKey<ElapsedMilliseconds() 
            Player(k)\waitkey=ElapsedMilliseconds()
            RunCommand(k,Game(),player(k)\Command(), Duet(),@player(k)\speed)
         Else
             RunCommand(k,Game(),player(k)\Command(), Duet(),@player(k)\speed)
        EndIf
    Next k
    ;}
    
    ;{- Applique les règles du jeu
    For k=0 To 1
        ;fait descendre le duo, au ralenti ou en accéléré
        If Player(k)\Timer+Player(k)\Speed<ElapsedMilliseconds() Or Player(k)\Bloc=1
            Player(k)\Timer=ElapsedMilliseconds()
            Player(k)\Bloc=gravityDuet(k,game(),duet())
        EndIf

        ;si il y a des trous, on les comble en faisant descendre le jeu
        If Player(k)\Void=1 Or Player(k)\ojama<>0
            Player(k)\moved=globalGravity(k,game(),duet())
        EndIf
        
        ;si on a un duo posé et que rien ne bouge plus
        If Player(k)\Bloc=2 And Player(k)\moved=0
            ;vérifie si il y a des paquets de 4 et plus, et on fait des trous
            Player(k)\Void=checkgame(k,game(),player())         
        EndIf
        
        ;si il n'y a pas de trou on envoie les ojama
        If Player(k)\Bloc=2 And Player(k)\moved=0 And Player(k)\Void=0
            Player(k)\ojama=AttaquePuyo(k,game(),player())
        EndIf
        
        ;si il n'y a pas d'ojama ni de trou et qu'on est posé on lance l'Ia
        If Player(k)\ojama=0 And Player(k)\Void=0 And Player(k)\Bloc=2
            NewDuet(k,game(),duet(),@Player(k)\NumDuet)
            Player(k)\Bloc=0
            Player(k)\StartIa=1
        EndIf
    Next k
    ;}

    saut:
Until KeyboardPushed(#PB_Key_Escape)
DataSection
    colors:
    Data.i #Redish,#Greenish,#Blueish,#Orange,#Purple,#Ojama
    keyboard0:
    Data.i #PB_Key_Up,#PB_Key_Down,#PB_Key_Left,#PB_Key_Right
    keyboard1:
    Data.i #PB_Key_F,#PB_Key_Space,#PB_Key_C,#PB_Key_V
EndDataSection

Re: Min/Max algo pour clone de Puyo-Puyo

Publié : mar. 06/nov./2018 20:58
par Ar-S
En état c'est sympathique de regarder l'IA jouer contre elle-même.
Carrément :!:

Re: Min/Max algo pour clone de Puyo-Puyo

Publié : mer. 07/nov./2018 12:29
par Kwai chang caine
En état c'est sympathique de regarder l'IA jouer contre elle-même.
Ca fait rêver la vitesse de réflexion 8O
Merci du partage 8)