Jump to content

Recommended Posts

2lorx0.jpg

... a little modified version; CPU vs CPU  ;)

#include <Array.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <Misc.au3>
#include <Sound.au3>
#include <WindowsConstants.au3>
#include <WinAPIRes.au3>

AutoItSetOption("MouseCoordMode", 0)
Opt("GUIOnEventMode", 1)
Opt("MustDeclareVars", 1)
;;-----------------------------------------------------------------------------------------------------------
Global Const $VERSION            = "1.0"
;; Image size ...
Global Const $GUI_WIDTH          = 800
Global Const $GUI_HEIGHT         = 600
Global Const $PIECE_WIDTH        = 64
Global Const $PIECE_HEIGHT       = 64
Global Const $TINY_PIECE_WIDTH   = 36
Global Const $TINY_PIECE_HEIGHT  = 36
;; Coordinates ...
;; to draw the little piece that indicate the color play by Player & CPU.
Global Const $PLAYER_COLOR_X     = 13
Global Const $PLAYER_COLOR_Y     = 127
Global Const $CPU_COLOR_X        = 751
Global Const $CPU_COLOR_Y        = 127
;; to draw the number of games won by Player & CPU.
Global Const $PLAYER_WON_GAMES_X = 55
Global Const $PLAYER_WON_GAMES_Y = 122
Global Const $CPU_WON_GAMES_X    = 709
Global Const $CPU_WON_GAMES_Y    = 122
;; to draw the Player Win image.
Global Const $PLAYER_WIN_X       = 236
Global Const $PLAYER_WIN_Y       = 200
;; to draw the CPU Win image.
Global Const $CPU_WIN_X          = 254
Global Const $CPU_WIN_Y          = 200
;; to draw the Draw image.
Global Const $DRAW_GAME_X        = 235
Global Const $DRAW_GAME_Y        = 200
;; to draw the "Play Again (Y/N)?" image.
Global Const $PLAY_AGAIN_X       = 155
Global Const $PLAY_AGAIN_Y       = 281
;; to draw the think image.
Global Const $PLAYER_THINK_X     = 28
Global Const $PLAYER_THINK_Y     = 243
Global Const $CPU_THINK_X        = 693
Global Const $CPU_THINK_Y        = 243
;; of board Row 0 & Column 0.
Global Const $COL0_X             = 143
Global Const $ROW0_Y             = 480
;; Board square width.
Global Const $SQUARE_WIDTH       = 75
;; Piece drop speed.
Global Const $DROP_SPEED         = 12
;; Piece & empty square.
Global Const $PLAYER             = 'P'
Global Const $CPU                = 'C'
Global Const $DRAW               = 'D'
Global Const $EMPTY_SQUARE       = '-'
;; Values for Minimax & Alpha Beta Pruning.
Global Const $INFINITY           = 10000
Global Const $MAX_DEPTH          = 4
Global Const $CPU_WIN_SCORE      = +$INFINITY / 10
Global Const $PLAYER_WIN_SCORE   = -$INFINITY / 10
Global Const $DRAW_SCORE         = 0
;; Patterns ...
Global Const $3C1E               = 3 * Asc($CPU) + Asc($EMPTY_SQUARE)
Global Const $3P1E               = 3 * Asc($PLAYER) + Asc($EMPTY_SQUARE)
Global Const $2C2E               = 2 * Asc($CPU) + 2 * Asc($EMPTY_SQUARE)
Global Const $2P2E               = 2 * Asc($PLAYER) + 2 * Asc($EMPTY_SQUARE)
Global Const $1C3E               = 1 * Asc($CPU) + 3 * Asc($EMPTY_SQUARE)
Global Const $1P3E               = 1 * Asc($PLAYER) + 3 * Asc($EMPTY_SQUARE)
;;-----------------------------------------------------------------------------------------------------------
Global $aWaitingSound     = _SoundOpen(@ScriptDir & "\Sounds\waiting.mid")
Global $aPlayerWinSound   = _SoundOpen(@ScriptDir & "\Sounds\player_win.wma")
Global $aCPUWinSound      = _SoundOpen(@ScriptDir & "\Sounds\cpu_win.wma")
Global $aDrawSound        = _SoundOpen(@ScriptDir & "\Sounds\draw.wma")
Global $aMoveSound        = _SoundOpen(@ScriptDir & "\Sounds\move.wma")
Global $aInValidMoveSound = _SoundOpen(@ScriptDir & "\Sounds\invalid_move.wma")
Global $aKeyPressSound    = _SoundOpen(@ScriptDir & "\Sounds\key_press.wma")
;;-----------------------------------------------------------------------------------------------------------
Global Const $hGUI = GUICreate("Connect 4", $GUI_WIDTH, $GUI_HEIGHT, -1, -1)
GUISetIcon(@ScriptDir & "\c4.ico", -1)
GUISetState(@SW_SHOW)
;;-----------------------------------------------------------------------------------------------------------
GUISetOnEvent($GUI_EVENT_CLOSE, "CloseApp", $hGUI)
GUISetOnEvent($GUI_EVENT_RESTORE, "DrawBoard", $hGUI)
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "PlayerMove", $hGUI)
GUIRegisterMsg($WM_MOVE, "WM_MOVE")
Func WM_MOVE($hWnd, $Msg, $wParam, $lParam)
    DrawBoard()
EndFunc
;;-----------------------------------------------------------------------------------------------------------
_GDIPlus_Startup()
Global Const $hFrameImg     = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\frame.png")
Global Const $hPlayerWinImg = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\player_win.png")
Global Const $hCPUWinImg    = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\cpu_win.png")
Global Const $hDrawImg      = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\draw.png")
Global Const $hPlayAgainImg = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\play_again.png")
Global Const $hThinkImg     = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\think.png")
Global Const $hMarkerImg    = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\marker.png")
Global Const $hDigit0Img    = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\0.png")
Global Const $hDigit1Img    = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\1.png")
Global Const $hDigit2Img    = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\2.png")
Global Const $hDigit3Img    = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\3.png")
Global Const $hDigit4Img    = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\4.png")
Global Const $hDigit5Img    = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\5.png")
Global Const $hDigit6Img    = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\6.png")
Global Const $hDigit7Img    = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\7.png")
Global Const $hDigit8Img    = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\8.png")
Global Const $hDigit9Img    = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Images\9.png")
Global Const $hGraphics     = _GDIPlus_GraphicsCreateFromHWND($hGUI)
Global Const $hBitmap       = _GDIPlus_BitmapCreateFromGraphics($GUI_WIDTH, $GUI_HEIGHT, $hGraphics)
Global Const $hBuffer       = _GDIPlus_ImageGetGraphicsContext($hBitmap)
Global Const $hBrushRed     = _GDIPlus_BrushCreateSolid(0xFFFF0000)
Global Const $hBrushYellow  = _GDIPlus_BrushCreateSolid(0xFFFFDE00)
Global Const $hBrushWhite   = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
Global Const $hPenPurple    = _GDIPlus_PenCreate(0xFF372248, 8)
;;-----------------------------------------------------------------------------------------------------------
Global $g_aBoard[6][7], $g_aState[9]
Global $g_iPlayerWonGames, $g_iCPUWonGames
Global $g_hPlayerColor, $g_hCPUColor
Global $g_sTurn, $g_iMove, $g_bDetectPlayerMove
;;-----------------------------------------------------------------------------------------------------------
_GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
_Connect4()
;;-----------------------------------------------------------------------------------------------------------

; CPU vs CPU
Func PlayerCPUMove()
    Local $iPieces = 7
    For $i = 0 to 6
        $iPieces -= $g_aBoard[0][$i] = "-"
    Next

    $g_bDetectPlayerMove = False

    If $iPieces Then
        $g_iMove = AI($g_aBoard)
    Else
        $g_iMove = Random(0, 6, 1)
    EndIf

    DrawBoard()
    _SoundPlay($aMoveSound, 1)
    $g_bDetectPlayerMove = True
    Return True
EndFunc   ;==>PlayerCPUMove

Func _Connect4()
    Initiate()
    DrawBoard()

    While True
        Select
            ;; Player turn.
            Case $g_sTurn = $PLAYER And PlayerCPUMove() ; PlayerMoved()
                $g_aState = CheckState($g_aBoard, $PLAYER)
                DrawBoard()
                Switch $g_aState[0]
                    Case "Win"
                        _SoundPlay($aPlayerWinSound)
                        Switch PlayAgain()
                            Case 'Y'
                                Reset()
                                DrawBoard()
                            Case 'N'
                                CloseApp()
                        EndSwitch
                    Case "Draw"
                        _SoundPlay($aDrawSound)
                        Switch PlayAgain()
                            Case 'Y'
                                Reset()
                                DrawBoard()
                            Case 'N'
                                CloseApp()
                        EndSwitch
                    Case "GoOn"
                        $g_sTurn = $CPU
                        DrawBoard()
                EndSwitch
            ;; CPU turn.
            Case $g_sTurn = $CPU And CPUMoved()
                $g_aState = CheckState($g_aBoard, $CPU)
                DrawBoard()
                Switch $g_aState[0]
                    Case "Win"
                        _SoundPlay($aCPUWinSound)
                        Switch PlayAgain()
                            Case 'Y'
                                Reset()
                                DrawBoard()
                            Case 'N'
                                CloseApp()
                        EndSwitch
                    Case "Draw"
                        _SoundPlay($aDrawSound)
                        Switch PlayAgain()
                            Case 'Y'
                                Reset()
                                DrawBoard()
                            Case 'N'
                                CloseApp()
                        EndSwitch
                    Case "GoOn"
                        $g_sTurn = $PLAYER
                        DrawBoard()
                EndSwitch
        EndSelect
    WEnd
EndFunc

Func AI($aBoard)
    Local $iRow, $iScore, $iBestMove, $iBestScore = -$INFINITY

    For $iMove = 0 To 6
        If IsValidMove($aBoard, $iMove) Then
            $iRow = PiecesInColumn($aBoard, $iMove)
            $aBoard[$iRow][$iMove] = $CPU
            $iScore = AlphaBeta($aBoard, $MAX_DEPTH, -$INFINITY, +$INFINITY, False)
            DisplayScore($iMove, $iScore)

            If $iScore > $iBestScore Then
                $iBestScore = $iScore
                $iBestMove = $iMove
            ElseIf $iScore = $iBestScore Then
                If Abs($iMove-3) < Abs($iBestMove-3) Then
                    $iBestMove = $iMove
                EndIf
            EndIf

            $aBoard[$iRow][$iMove] = $EMPTY_SQUARE
        EndIf
    Next

    Return $iBestMove
EndFunc

Func CheckState($aBoard, $sSide)
    Local $aState[9] = ["GoOn", -1, -1, -1, -1, -1, -1, -1, -1]
    Local $bBoardFull = True

    For $iRow = 0 To 5
        For $iCol = 0 To 6
            If $aBoard[$iRow][$iCol] <> $EMPTY_SQUARE Then
                ;; Check horizontal.
                If $iCol+3 <= 6 Then
                    If $aBoard[$iRow][$iCol] = $sSide And $aBoard[$iRow][$iCol+1] = $sSide And _
                        $aBoard[$iRow][$iCol+2] = $sSide And $aBoard[$iRow][$iCol+3] = $sSide Then
                        $aState[0] = "Win"
                        $aState[1] = $iRow
                        $aState[2] = $iCol
                        $aState[3] = $iRow
                        $aState[4] = $iCol+1
                        $aState[5] = $iRow
                        $aState[6] = $iCol+2
                        $aState[7] = $iRow
                        $aState[8] = $iCol+3
                        Return $aState
                    EndIf
                EndIf
                ;; Check vertical.
                If $iRow+3 <= 5 Then
                    If $aBoard[$iRow][$iCol] = $sSide And $aBoard[$iRow+1][$iCol] = $sSide And _
                        $aBoard[$iRow+2][$iCol] = $sSide And $aBoard[$iRow+3][$iCol] = $sSide Then
                        $aState[0] = "Win"
                        $aState[1] = $iRow
                        $aState[2] = $iCol
                        $aState[3] = $iRow+1
                        $aState[4] = $iCol
                        $aState[5] = $iRow+2
                        $aState[6] = $iCol
                        $aState[7] = $iRow+3
                        $aState[8] = $iCol
                        Return $aState
                    EndIf
                EndIf
                ;; Check ascending diagonal.
                If $iRow+3 <= 5 And $iCol+3 <= 6 Then
                    If $aBoard[$iRow][$iCol] = $sSide And $aBoard[$iRow+1][$iCol+1] = $sSide And _
                        $aBoard[$iRow+2][$iCol+2] = $sSide And $aBoard[$iRow+3][$iCol+3] = $sSide Then
                        $aState[0] = "Win"
                        $aState[1] = $iRow
                        $aState[2] = $iCol
                        $aState[3] = $iRow+1
                        $aState[4] = $iCol+1
                        $aState[5] = $iRow+2
                        $aState[6] = $iCol+2
                        $aState[7] = $iRow+3
                        $aState[8] = $iCol+3
                        Return $aState
                    EndIf
                EndIf
                ;; Check descending diagonal.
                If $iRow-3 >= 0 And $iCol+3 <= 6 Then
                    If $aBoard[$iRow][$iCol] = $sSide And $aBoard[$iRow-1][$iCol+1] = $sSide And _
                        $aBoard[$iRow-2][$iCol+2] = $sSide And $aBoard[$iRow-3][$iCol+3] = $sSide Then
                        $aState[0] = "Win"
                        $aState[1] = $iRow
                        $aState[2] = $iCol
                        $aState[3] = $iRow-1
                        $aState[4] = $iCol+1
                        $aState[5] = $iRow-2
                        $aState[6] = $iCol+2
                        $aState[7] = $iRow-3
                        $aState[8] = $iCol+3
                        Return $aState
                    EndIf
                EndIf
            Else
                $bBoardFull = False
            EndIf
        Next
    Next

    If $bBoardFull Then
        $aState[0] = "Draw"
    EndIf

    Return $aState
EndFunc

Func CloseApp()
    _SoundClose($aWaitingSound)
    _SoundClose($aPlayerWinSound)
    _SoundClose($aCPUWinSound)
    _SoundClose($aDrawSound)
    _SoundClose($aMoveSound)
    _SoundClose($aInValidMoveSound)
    _SoundClose($aKeyPressSound)
    _GDIPlus_PenDispose($hPenPurple)
    _GDIPlus_BrushDispose($hBrushWhite)
    _GDIPlus_BrushDispose($hBrushYellow)
    _GDIPlus_BrushDispose($hBrushRed)
    _GDIPlus_GraphicsDispose($hBuffer)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    GUIDelete($hGUI)
    Exit
EndFunc

Func CPUMoved()
    $g_bDetectPlayerMove = False
    $g_iMove = AI($g_aBoard)
    DrawBoard()
    _SoundPlay($aMoveSound, 1)
    $g_bDetectPlayerMove = True
    Return True
EndFunc

Func DisplayScore($iCol, $iScore)
    Local Static $iLastCol = 0, $sScore

    If $iCol <= $iLastCol Then
        $sScore = ''
        $sScore = $sScore &  "   " & $iCol+1 & " = " & $iScore
    Else
        $sScore = $sScore &  " | " & $iCol+1 & " = " & $iScore
    EndIf

    $iLastCol = $iCol
    WinSetTitle($hGUI, "", "Connect 4" & $sScore)
EndFunc

Func DrawBoard()
    Local $iX, $iY, $iTopPieceY, $iPiecesInColumn
    Local Static $iLastMove = -1

    $g_bDetectPlayerMove = False

    If $g_iMove > -1 Then
        $iX = $COL0_X+$g_iMove*$SQUARE_WIDTH
        $iY = $ROW0_Y-6*$SQUARE_WIDTH
        $iPiecesInColumn = PiecesInColumn($g_aBoard, $g_iMove)
        $iTopPieceY = $ROW0_Y-$iPiecesInColumn * $SQUARE_WIDTH

        Do
            DrawBackground()
            DrawPiecesOnBoard()
            DrawPieceDropping($iX, $iY)
            DrawFrame()
            DrawColorIndicators()
            DrawWinCounter()
            DrawWhoseTurn()
            DrawBufferToGUI()
        Until $iY > $iTopPieceY

        $g_aBoard[$iPiecesInColumn][$g_iMove] = $g_sTurn
        $iLastMove = $g_iMove
        $g_iMove = -1
    EndIf

    DrawBackground()
    DrawPiecesOnBoard()
    DrawFrame()
    DrawColorIndicators()
    DrawWinCounter()
    DrawWhoseTurn()
    DrawMoveMarker($iLastMove)

    Switch $g_aState[0]
        Case "Win"
            For $iIdx = 1 To 8 Step 2
                $iX = $COL0_X+$g_aState[$iIdx+1]*$SQUARE_WIDTH
                $iY = $ROW0_Y-$g_aState[$iIdx]*$SQUARE_WIDTH
                _GDIPlus_GraphicsDrawEllipse($hBuffer, $iX, $iY, $PIECE_WIDTH, $PIECE_HEIGHT, $hPenPurple)
            Next
            Switch $g_sTurn
                Case $PLAYER
                    DrawPlayerWin()
                Case $CPU
                    DrawCPUWin()
            EndSwitch
            DrawPlayAgain()
            $iLastMove = -1
        Case "Draw"
            DrawItsADraw()
            DrawPlayAgain()
            $iLastMove = -1
    EndSwitch

    DrawBufferToGUI()
    $g_bDetectPlayerMove = True
EndFunc

Func DrawBackground()
    _GDIPlus_GraphicsFillRect($hBuffer, 0, 0, $GUI_WIDTH, $GUI_HEIGHT, $hBrushWhite)
EndFunc

Func DrawBufferToGUI()
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $GUI_WIDTH, $GUI_HEIGHT)
EndFunc

Func DrawColorIndicators()
    _GDIPlus_GraphicsFillEllipse($hBuffer, $PLAYER_COLOR_X, $PLAYER_COLOR_Y, $TINY_PIECE_WIDTH, $TINY_PIECE_HEIGHT, $g_hPlayerColor)
    _GDIPlus_GraphicsFillEllipse($hBuffer, $CPU_COLOR_X, $CPU_COLOR_Y, $TINY_PIECE_WIDTH, $TINY_PIECE_HEIGHT, $g_hCPUColor)
EndFunc

Func DrawFrame()
    _GDIPlus_GraphicsDrawImageRect($hBuffer, $hFrameImg, 0, 0, $GUI_WIDTH, $GUI_HEIGHT)
EndFunc

Func DrawMoveMarker($iLastMove)
    Local $aX = [155, 231, 306, 381, 455, 532, 605], $iY = 550
    Local $iImgWidth, $iImgHeight

    If $iLastMove > -1 Then
        $iImgWidth = _GDIPlus_ImageGetWidth($hMarkerImg)
        $iImgHeight = _GDIPlus_ImageGetHeight($hMarkerImg)
        _GDIPlus_GraphicsDrawImageRect($hBuffer, $hMarkerImg, $aX[$iLastMove], $iY, $iImgWidth, $iImgHeight)
    EndIf
EndFunc

Func DrawPieceDropping($iX, ByRef $iY)
    Switch $g_sTurn
        Case $PLAYER
            _GDIPlus_GraphicsFillEllipse($hBuffer, $iX, $iY, $PIECE_WIDTH, $PIECE_HEIGHT, $g_hPlayerColor)
        Case $CPU
            _GDIPlus_GraphicsFillEllipse($hBuffer, $iX, $iY, $PIECE_WIDTH, $PIECE_HEIGHT, $g_hCPUColor)
    EndSwitch

    $iY += $DROP_SPEED
EndFunc

Func DrawPiecesOnBoard()
    Local $iX, $iY

    For $iRow = 0 To 5
        For $iCol = 0 To 6
            $iX = $COL0_X+$iCol*$SQUARE_WIDTH
            $iY = $ROW0_Y-$iRow*$SQUARE_WIDTH
            Switch $g_aBoard[$iRow][$iCol]
                Case $PLAYER
                    _GDIPlus_GraphicsFillEllipse($hBuffer, $iX, $iY, $PIECE_WIDTH, $PIECE_HEIGHT, $g_hPlayerColor)
                Case $CPU
                    _GDIPlus_GraphicsFillEllipse($hBuffer, $iX, $iY, $PIECE_WIDTH, $PIECE_HEIGHT, $g_hCPUColor)
            EndSwitch
        Next
    Next
EndFunc

Func DrawCPUWin()
    Local $iImgWidth, $iImgHeight

    $iImgWidth = _GDIPlus_ImageGetWidth($hCPUWinImg)
    $iImgHeight = _GDIPlus_ImageGetHeight($hCPUWinImg)
    _GDIPlus_GraphicsDrawImageRect($hBuffer, $hCPUWinImg, $CPU_WIN_X, $CPU_WIN_Y, $iImgWidth, $iImgHeight)
EndFunc

Func DrawItsADraw()
    Local $iImgWidth, $iImgHeight

    $iImgWidth = _GDIPlus_ImageGetWidth($hDrawImg)
    $iImgHeight = _GDIPlus_ImageGetHeight($hDrawImg)
    _GDIPlus_GraphicsDrawImageRect($hBuffer, $hDrawImg, $DRAW_GAME_X, $DRAW_GAME_Y, $iImgWidth, $iImgHeight)
EndFunc

Func DrawPlayAgain()
    Local $iImgWidth, $iImgHeight

    $iImgWidth = _GDIPlus_ImageGetWidth($hPlayAgainImg)
    $iImgHeight = _GDIPlus_ImageGetHeight($hPlayAgainImg)
    _GDIPlus_GraphicsDrawImageRect($hBuffer, $hPlayAgainImg, $PLAY_AGAIN_X, $PLAY_AGAIN_Y, $iImgWidth, $iImgHeight)
EndFunc

Func DrawPlayerWin()
    Local $iImgWidth, $iImgHeight

    $iImgWidth = _GDIPlus_ImageGetWidth($hPlayerWinImg)
    $iImgHeight = _GDIPlus_ImageGetHeight($hPlayerWinImg)
    _GDIPlus_GraphicsDrawImageRect($hBuffer, $hPlayerWinImg, $PLAYER_WIN_X, $PLAYER_WIN_Y, $iImgWidth, $iImgHeight)
EndFunc

Func DrawWinCounter()
    Local $aDigitImg[10] = [$hDigit0Img, $hDigit1Img, $hDigit2Img, $hDigit3Img, $hDigit4Img, $hDigit5Img, $hDigit6Img, $hDigit7Img, $hDigit8Img, $hDigit9Img]
    Local $sPlayerWonGames = String($g_iPlayerWonGames), $sCPUWonGames = StringReverse(String($g_iCPUWonGames))
    Local $aDigit, $iDigitImgWidth, $iDigitImgHeight, $iXP = $PLAYER_WON_GAMES_X, $iXC = $CPU_WON_GAMES_X

    $aDigit = StringSplit($sPlayerWonGames, '')

    For $iIdx = 1 To $aDigit[0]
        $iDigitImgWidth  = _GDIPlus_ImageGetWidth($aDigitImg[$aDigit[$iIdx]])
        $iDigitImgHeight = _GDIPlus_ImageGetHeight($aDigitImg[$aDigit[$iIdx]])
        _GDIPlus_GraphicsDrawImageRect($hBuffer, $aDigitImg[$aDigit[$iIdx]], $iXP, $PLAYER_WON_GAMES_Y, $iDigitImgWidth, $iDigitImgHeight)
        $iXP += $iDigitImgWidth-5
    Next

    $aDigit = StringSplit($sCPUWonGames, '')

    For $iIdx = 1 To $aDigit[0]
        $iDigitImgWidth  = _GDIPlus_ImageGetWidth($aDigitImg[$aDigit[$iIdx]])
        $iDigitImgHeight = _GDIPlus_ImageGetHeight($aDigitImg[$aDigit[$iIdx]])
        _GDIPlus_GraphicsDrawImageRect($hBuffer, $aDigitImg[$aDigit[$iIdx]], $iXC, $CPU_WON_GAMES_Y, $iDigitImgWidth, $iDigitImgHeight)
        If $iIdx < $aDigit[0] Then
            $iDigitImgWidth  = _GDIPlus_ImageGetWidth($aDigitImg[$aDigit[$iIdx+1]])
            $iXC -= $iDigitImgWidth-5
        EndIf
    Next
EndFunc

Func DrawWhoseTurn()
    Local $iImgWidth, $iImgHeight

    $iImgWidth = _GDIPlus_ImageGetWidth($hThinkImg)
    $iImgHeight = _GDIPlus_ImageGetHeight($hThinkImg)

    Switch $g_sTurn
        Case $PLAYER
            _GDIPlus_GraphicsDrawImageRect($hBuffer, $hThinkImg, $PLAYER_THINK_X, $PLAYER_THINK_Y, $iImgWidth, $iImgHeight)
        Case $CPU
            _GDIPlus_GraphicsDrawImageRect($hBuffer, $hThinkImg, $CPU_THINK_X, $CPU_THINK_Y, $iImgWidth, $iImgHeight)
    EndSwitch
EndFunc

Func Initiate()
    For $iRow = 0 To 5
        For $iCol = 0 To 6
            $g_aBoard[$iRow][$iCol] = $EMPTY_SQUARE
        Next
    Next

    $g_iPlayerWonGames = 0
    $g_iCPUWonGames = 0
    $g_hPlayerColor = $hBrushRed
    $g_hCPUColor = $hBrushYellow
    $g_sTurn = $PLAYER
    $g_iMove = -1
    $g_bDetectPlayerMove = True
EndFunc

Func IsValidMove($aBoard, $iMove)
    Return ($aBoard[5][$iMove] = $EMPTY_SQUARE) ? True : False
EndFunc

Func Max($iA, $iB)
    Return ($iA > $iB) ? $iA : $iB
EndFunc

Func Min($iA, $iB)
    Return ($iA < $iB) ? $iA : $iB
EndFunc

Func PiecesInColumn($aBoard, $iCol)
    Local $iPiecesInColumn = 0

    For $iRow = 0 To 5
        If $aBoard[$iRow][$iCol] = $EMPTY_SQUARE Then
            ExitLoop
        Else
            $iPiecesInColumn += 1
        EndIf
    Next

    Return $iPiecesInColumn
EndFunc

Func PlayAgain()
    Local $hDLL = DllOpen("user32.dll"), $sAnswer

    $g_bDetectPlayerMove = False
    _SoundPlay($aWaitingSound)

    While True
        Select
            Case _IsPressed('59')
                $sAnswer = 'Y'
                ExitLoop
            Case _IsPressed('4E')
                $sAnswer = 'N'
                ExitLoop
        EndSelect
    WEnd

    _SoundPlay($aKeyPressSound, 1)
    _SoundPause($aWaitingSound)
    DllClose($hDLL)
    $g_bDetectPlayerMove = True
    Return $sAnswer
EndFunc

Func PlayerMove()
    Local $iX = MouseGetPos(0), $iY = MouseGetPos(1)

    If $g_bDetectPlayerMove Then
        If  $iY > 130 And $iY < 568 Then
            Select
                Case $iX > 143 And $iX < 207
                    $g_iMove = 0
                Case $iX > 218 And $iX < 282
                    $g_iMove = 1
                Case $iX > 293 And $iX < 357
                    $g_iMove = 2
                Case $iX > 368 And $iX < 432
                    $g_iMove = 3
                Case $iX > 443 And $iX < 507
                    $g_iMove = 4
                Case $iX > 518 And $iX < 582
                    $g_iMove = 5
                Case $iX > 593 And $iX < 657
                    $g_iMove = 6
            EndSelect
        EndIf

        If $g_iMove > -1 Then
            If Not(IsValidMove($g_aBoard, $g_iMove)) Then
                _SoundPlay($aInValidMoveSound, 1)
                $g_iMove = -1
            EndIf
        EndIf
    EndIf
EndFunc

Func PlayerMoved()
    If $g_iMove > -1 Then
        DrawBoard()
        _SoundPlay($aMoveSound, 1)
        Return True
    Else
        Return False
    EndIf
EndFunc

Func Reset()
    WinSetTitle($hGUI, "", "Connect 4")

    Select
        Case $g_sTurn = $PLAYER And $g_aState[0] = "Win"
            $g_iPlayerWonGames += 1
        Case $g_sTurn = $CPU And $g_aState[0] = "Win"
            $g_iCPUWonGames += 1
    EndSelect

    Swap($g_hPlayerColor, $g_hCPUColor)

    Select
        Case $g_hPlayerColor = $hBrushRed
            $g_sTurn = $PLAYER
        Case $g_hCPUColor = $hBrushRed
            $g_sTurn = $CPU
    EndSelect

    For $iRow = 0 To 5
        For $iCol = 0 To 6
            $g_aBoard[$iRow][$iCol] = $EMPTY_SQUARE
        Next
    Next

    $g_aState[0] = "GoOn"
    For $iIdx = 1 To 8
        $g_aState[$iIdx] = -1
    Next
EndFunc

Func Swap(ByRef $A, ByRef $B)
    Local $Temp = $A

    $A = $B
    $B = $Temp
EndFunc
;;-----------------------------------------------------------------------------------------------------------
Func AlphaBeta($aNode, $iDepth, $iAlpha, $iBeta, $bMaximizingPlayer)
    Local $aChildNodes[7], $iV, $iNumOfNodes, $sState

    If $iDepth = 0 Or IsTerminal($aNode, $sState) Then
        Return Score($aNode, $iDepth, $sState)
    EndIf

    If $bMaximizingPlayer Then
        $iV = -$INFINITY
        GetChildNodes($aNode, $CPU, $iNumOfNodes, $aChildNodes)

        For $iIdx = 0 To $iNumOfNodes-1
            $iV = Max($iV, AlphaBeta($aChildNodes[$iIdx], $iDepth-1, $iAlpha, $iBeta, False))
            $iAlpha = Max($iAlpha, $iV)
            If $iBeta <= $iAlpha Then
                ExitLoop
            EndIf
        Next

        Return $iV
    Else
        $iV = +$INFINITY
        GetChildNodes($aNode, $PLAYER, $iNumOfNodes, $aChildNodes)

        For $iIdx = 0 To $iNumOfNodes-1
            $iV = Min($iV, AlphaBeta($aChildNodes[$iIdx], $iDepth-1, $iAlpha, $iBeta, True))
            $iBeta = Min($iBeta, $iV)
            If $iBeta <= $iAlpha Then
                ExitLoop
            EndIf
        Next

        Return $iV
    EndIf
EndFunc

Func GetChildNodes($aNode, $sSide, ByRef $iNumOfNodes, ByRef $aChildNodes)
    Local $aMoveOrder = [3, 2, 4, 1, 5, 0, 6]
    Local $iRow

    $iNumOfNodes = 0

    For $iIdx = 0 To 6
        If IsValidMove($aNode, $aMoveOrder[$iIdx]) Then
            $iRow = PiecesInColumn($aNode, $aMoveOrder[$iIdx])
            $aNode[$iRow][$aMoveOrder[$iIdx]] = $sSide
            $aChildNodes[$iNumOfNodes] = $aNode
            $aNode[$iRow][$aMoveOrder[$iIdx]] = $EMPTY_SQUARE
            $iNumOfNodes += 1
        EndIf
    Next
EndFunc

Func IsTerminal($aNode, ByRef $sResult)
    Local $bBoardFull = True

    For $iRow = 0 To 5
        For $iCol = 0 To 6
            If $aNode[$iRow][$iCol] <> $EMPTY_SQUARE Then
                ;; Check horizontal.
                If $iCol+3 <= 6 Then
                    If $aNode[$iRow][$iCol] = $aNode[$iRow][$iCol+1] And _
                        $aNode[$iRow][$iCol+1] = $aNode[$iRow][$iCol+2] And _
                        $aNode[$iRow][$iCol+2] = $aNode[$iRow][$iCol+3] Then
                        $sResult = $aNode[$iRow][$iCol]
                        Return True
                    EndIf
                EndIf
                ;; Check vertical.
                If $iRow+3 <= 5 Then
                    If $aNode[$iRow][$iCol] = $aNode[$iRow+1][$iCol] And _
                        $aNode[$iRow+1][$iCol] = $aNode[$iRow+2][$iCol] And _
                        $aNode[$iRow+2][$iCol] = $aNode[$iRow+3][$iCol] Then
                        $sResult = $aNode[$iRow][$iCol]
                        Return True
                    EndIf
                EndIf
                ;; Check ascending diagonal.
                If $iRow+3 <= 5 And $iCol+3 <= 6 Then
                    If $aNode[$iRow][$iCol] = $aNode[$iRow+1][$iCol+1] And _
                        $aNode[$iRow+1][$iCol+1] = $aNode[$iRow+2][$iCol+2] And _
                        $aNode[$iRow+2][$iCol+2] = $aNode[$iRow+3][$iCol+3] Then
                        $sResult = $aNode[$iRow][$iCol]
                        Return True
                    EndIf
                EndIf
                ;; Check descending diagonal.
                If $iRow-3 >= 0 And $iCol+3 <= 6 Then
                    If $aNode[$iRow][$iCol] = $aNode[$iRow-1][$iCol+1] And _
                        $aNode[$iRow-1][$iCol+1] = $aNode[$iRow-2][$iCol+2] And _
                        $aNode[$iRow-2][$iCol+2] = $aNode[$iRow-3][$iCol+3] Then
                        $sResult = $aNode[$iRow][$iCol]
                        Return True
                    EndIf
                EndIf
            Else
                $bBoardFull = False
            Endif
        Next
    Next

    If $bBoardFull Then
        $sResult = $DRAW
        Return True
    Else
        $sResult = "None"
        Return False
    EndIf
EndFunc

Func Score($aNode, $iDepth, $sState)
    Local $iScore = 0

    Switch $sState
        Case "None"
        Case $CPU
            Return $CPU_WIN_SCORE+$iDepth
        Case $PLAYER
            Return $PLAYER_WIN_SCORE-$iDepth
        Case $DRAW
            Return $DRAW_SCORE
    EndSwitch

    For $iRow = 0 To 5
        For $iCol = 0 To 6
            If $aNode[$iRow][$iCol] = $EMPTY_SQUARE Then
                ;; Calculate left.
                If $iRow-3 >= 0 Then
                    Evaluate(Asc($aNode[$iRow][$iCol])+Asc($aNode[$iRow-1][$iCol])+Asc($aNode[$iRow-2][$iCol])+Asc($aNode[$iRow-3][$iCol]), $iScore)
                EndIf
                ;; Calculate upper left.
                If $iRow+3 <= 5 And $iCol-3 >= 0 Then
                    Evaluate(Asc($aNode[$iRow][$iCol])+Asc($aNode[$iRow+1][$iCol-1])+Asc($aNode[$iRow+2][$iCol-2])+Asc($aNode[$iRow+3][$iCol-3]), $iScore)
                EndIf
                ;; Calculate up.
                If $iRow+3 <= 5 Then
                    Evaluate(Asc($aNode[$iRow][$iCol])+Asc($aNode[$iRow+1][$iCol])+Asc($aNode[$iRow+2][$iCol])+Asc($aNode[$iRow+3][$iCol]), $iScore)
                EndIf
                ;; Calculate upper right.
                If $iRow+3 <= 5 And $iCol+3 <= 6 Then
                    Evaluate(Asc($aNode[$iRow][$iCol])+Asc($aNode[$iRow+1][$iCol+1])+Asc($aNode[$iRow+2][$iCol+2])+Asc($aNode[$iRow+3][$iCol+3]), $iScore)
                EndIf
                ;; Calculate right.
                If $iCol+3 <= 6 Then
                    Evaluate(Asc($aNode[$iRow][$iCol])+Asc($aNode[$iRow][$iCol+1])+Asc($aNode[$iRow][$iCol+2])+Asc($aNode[$iRow][$iCol+3]), $iScore)
                EndIf
            EndIf
        Next
    Next

    Return $iScore
EndFunc

Func Evaluate($iSum, ByRef $iScore)
    Switch $iSum
        Case $3C1E
            $iScore += 24
        Case $3P1E
            $iScore += -24
        Case $2C2E
            $iScore += 8
        Case $2P2E
            $iScore += -8
        Case $1C3E
            $iScore += 2
        Case $1P3E
            $iScore += -2
    EndSwitch
EndFunc

 

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to post
Share on other sites

Nice implementation. :thumbsup:

 

But when when the score is even (all coins were used) the game doesn't end -> no "it is a draw" message.

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to post
Share on other sites

Hi, I just upload a new version 2.0 to solve a problem, In version 1.0 when we reach an end position(either
CPU or Player win) with two groups of "connect 4" pieces join together, the program just highlight one group, now
both groups will be highlighted, and I change the search algorithm from MiniMax to NegaMax, it's a bit faster now.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Chimp
      After watching this movie (https://www.youtube.com/watch?v=cPiDHXtM0VA) I wanted to try the test to see how much i could compete with that chimpanzee so i created this script.
      well, actually passing that test is a lot harder than it sounds. With the difficulty set to seven numbers and a display time of one second, I can only remember 2 or 3 numbers ... (what a disappointment)
      I can only do better if I reduce the slider to 5 numbers and increase the storage time to 2 seconds (the easyest level), a very poor performance. That chimpanzee is great.
      The script offers you a sequence of 10 random quizzes. At the end it gives you the percentage of your "level". The chimpanzee resolves on average 8 out of 10 (80%), so you can compare your performance to that of the chimpanzee.
      How to play:
      Run the script. At the beginning there are 2 sliders at the bottom of the screen where you can set the difficulty level by varying the memorization time and the amount of numbers to memorize as you like. After setting the difficulty, click the circle on the bottom left to get started. after the first move the sliders are no longer displayed until the next game, (the game lasts 10 attempts, there is a progress bar at the bottom of the screen to see where you are) between one test and the other of the ten, click on the circle to move on to the next test have fun.
      (here a related interesting video: https://www.youtube.com/watch?v=ktkjUjcZid0 )
      #include <GUIConstants.au3> #include <MsgBoxConstants.au3> #include <Array.au3> #include <WinAPIMisc.au3> ; HotKeySet("{ESC}", "_EndOfGame") Global $iNumbersToGuess = 7, $iExpositionTime = 1000, $iMatches = 10, $iMatchesWon Global $aNumbers[10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Global $aButtons[10], $aControls[5] Global $iWinWidth = @DesktopWidth / 2, $iWinHeight = @DesktopHeight / 2, $iButtonXSide = Int($iWinWidth / UBound($aNumbers)), $iButtonYSide = Int($iWinHeight / UBound($aNumbers)), $sWinTitle = "Beat the Chimp" Global $aX[Int($iWinWidth / $iButtonXSide)], $aY[Int($iWinHeight / $iButtonYSide)], $iNdx = 0, $aPoints[3], $score, $GUIGetMsg, $iDockHeight = 50, $iProgrssHeight = 5 For $i = 0 To (Int($iWinWidth / $iButtonXSide) - 1) * $iButtonXSide Step $iButtonXSide $aX[$iNdx] = $i $iNdx += 1 Next $iNdx = 0 For $i = 0 To (Int($iWinHeight / $iButtonYSide) - 1) * $iButtonYSide Step $iButtonYSide $aY[$iNdx] = $i $iNdx += 1 Next Global Const $iDockLeftBorder = 200, $iForeColor = 0xFFFFFF, $iBackColor = 0x000000 Global $hGUI = GUICreate($sWinTitle, $iWinWidth, $iWinHeight + $iDockHeight + $iProgrssHeight, @DesktopWidth / 4, @DesktopHeight / 5) GUISetBkColor($iBackColor, $hGUI) ; the circle to continue playing $aControls[0] = GUICtrlCreateLabel(ChrW(0x25EF), 0, $iWinHeight + 1, 100, $iDockHeight, 0x01) ; GUICtrlSetTip(-1, "Click the circle," & @CRLF & "then click the squares" & @CRLF & "in numeric order.") GUICtrlSetFont(-1, 24, 900) GUICtrlSetColor(-1, $iForeColor) GUICtrlSetBkColor(-1, $iBackColor) ; slider for the amount of numbers to guess $aControls[2] = GUICtrlCreateSlider($iDockLeftBorder, $iWinHeight, $iWinWidth - $iDockLeftBorder, Int($iDockHeight / 2)) GUICtrlSetLimit(-1, 10, 5) ; 5 steps 5 (easy) to 10 (hard) GUICtrlSetData(-1, $iNumbersToGuess) ; label for the amount of quizzes $aControls[1] = GUICtrlCreateLabel("Numbers : " & GUICtrlRead($aControls[2]), 100, $iWinHeight + 1, 100) GUICtrlSetColor(-1, $iForeColor) ; slider for the exposition time $aControls[4] = GUICtrlCreateSlider($iDockLeftBorder, $iWinHeight + (Int($iDockHeight / 2)), $iWinWidth - $iDockLeftBorder, $iDockHeight / 2) GUICtrlSetLimit(-1, 8, 1) ; 8 steps (0f 250ms each) GUICtrlSetData(-1, $iExpositionTime / 250) ; label for the exposition time $aControls[3] = GUICtrlCreateLabel("ms to show : " & GUICtrlRead($aControls[4]) * 250, 100, $iWinHeight + 1 + (Int($iDockHeight / 2)), 100) GUICtrlSetColor(-1, $iForeColor) ; progress bar of the match Global $idProgressbar = GUICtrlCreateProgress(0, $iWinHeight + $iDockHeight, $iWinWidth, $iProgrssHeight) ; Create buttons For $i = 0 To 9 $aButtons[$i] = GUICtrlCreateLabel($i + 1, $iWinWidth + 5, $iWinHeight + $iDockHeight + $iProgrssHeight + 5, $iButtonXSide, $iButtonYSide, 0x01) GUICtrlSetFont($aButtons[$i], 24) GUICtrlSetColor($aButtons[$i], $iForeColor) GUICtrlSetBkColor($aButtons[$i], $iBackColor) Next GUISetState(@SW_SHOW) ; --- Main loop --- Do ; New game $iMatchesWon = 0 GUICtrlSetData($idProgressbar, 0) For $iRound = 1 To $iMatches ; the game lasts $iMatches rounds $iNdx = 0 ; reset pointer (index to the next correct answer) _HideControls(__get_IDs_by_indexes($aButtons, $aNumbers)) ; remove the numbers from the screen ; show the dock and wait (only in the first round are also shown the sliders) _ShowControls($iRound = 1 ? $aControls : $aControls[0]) ; display the dock's control(s) While 1 Switch GUIGetMsg() Case $aControls[0] ; The circle (play a new quiz) ExitLoop Case $aControls[2] ; slider to choose how many numbers to guess $iNumbersToGuess = GUICtrlRead($aControls[2]) GUICtrlSetData($aControls[1], "Numbers : " & $iNumbersToGuess) Case $aControls[4] ; slider to choose how long (milliseconds) to show the numbers $iExpositionTime = GUICtrlRead($aControls[4]) * 250 ; 8 steps of 250 milliseconds each GUICtrlSetData($aControls[3], "ms to show : " & $iExpositionTime) Case $GUI_EVENT_CLOSE _EndOfGame() EndSwitch WEnd _HideControls($aControls) ; hide the dock Sleep(750) ; wait a bit $aQuiz = _GenerateQuiz($iNumbersToGuess) ; generate random elements to guess _SpreadControls(__get_IDs_by_indexes($aButtons, $aQuiz)) ; scatter the numbers on the GUI _ShowControls(__get_IDs_by_indexes($aButtons, $aQuiz)) ; display the numbers Sleep($iExpositionTime) ; leave numbers visible for a short time _MaskControls(__get_IDs_by_indexes($aButtons, $aQuiz)) ; mask the numbers GUICtrlSetData($idProgressbar, Round($iRound / $iMatches * 100)) ; _ShowControls(__get_IDs_by_indexes($aButtons, $aQuiz)) ; <------------- keep numbers visible FOR DEBUG PURPOSE ONLY! While 1 ; wait for a move $GUIGetMsg = GUIGetMsg() If $GUIGetMsg = $GUI_EVENT_CLOSE Then _EndOfGame() ; scan all quiz buttons to check if one was pressed For $i = 0 To UBound($aQuiz) - 1 ; $aButtons) - 1 If $GUIGetMsg = $aButtons[$aQuiz[$i] - 1] Then If $i = $iNdx Then ; -------------------------- ; actions for a right move ; -------------------------- ; hide the guessed number _HideControls($aButtons[$aQuiz[$i] - 1]) ; --------------------------------- ; check if this round is complete ; --------------------------------- If $iNdx = (UBound($aQuiz) - 1) Then _WinAPI_PlaySound("SystemExclamation", Null, BitOR($SND_ALIAS, $SND_ASYNC)) $iMatchesWon += 1 ExitLoop 2 EndIf ; play a short ok sound ; _WinAPI_PlaySound("FaxBeep", Null, BitOR($SND_ALIAS, $SND_ASYNC)) ; "SystemAsterisk" $iNdx += 1 ; set index to next correct answer Else ; -------------------------- ; actions for a wrong move ; -------------------------- ; show all the right sequence _ShowControls(__get_IDs_by_indexes($aButtons, $aQuiz)) _WinAPI_PlaySound("DeviceFail", Null, BitOR($SND_ALIAS, $SND_ASYNC)) ; give a little time to the user to control it Sleep(1500) ; go to next step ExitLoop 2 EndIf EndIf Next WEnd ; loop till end of match $score = Round($iMatchesWon / $iMatches * 100, 2) ; percentage Select Case $score < 80 $sResult = "The chimp beat you!" Case $score > 80 $sResult = "You beat the chimp!" Case $score = 80 $sResult = "You tied the chimp." EndSelect Next ; next round ; game over? Until MsgBox($MB_YESNO + $MB_ICONINFORMATION + $MB_TASKMODAL + $MB_SETFOREGROUND, _ "Game over", _ "You got " & $score & "% correct." & @CRLF & _ "Ayumu averages 80% correct." & @CRLF & $sResult & @CRLF & @CRLF & _ "do you want to try again?") <> 6 Func _SpreadControls($aTemp) ; place the required numbers scattered on the GUI SRandom(@YEAR + @MON + @MDAY + @HOUR + @MIN + @SEC) _ArrayShuffle($aX) _ArrayShuffle($aY) ; first, place all buttons out of GUI For $i = 0 To UBound($aButtons) - 1 GUICtrlSetPos($aButtons[$i], $iWinWidth + 5, $iWinHeight + $iDockHeight + $iProgrssHeight + 5) GUICtrlSetState($aButtons[$i], $GUI_DISABLE) Next ; Then place only the numbers of this quiz in visible area For $i = 0 To UBound($aTemp) - 1 GUICtrlSetPos($aTemp[$i], $aX[$i], $aY[$i]) GUICtrlSetState($aTemp[$i], $GUI_ENABLE) Next EndFunc ;==>_SpreadControls Func _GenerateQuiz($iNumElements) ; generate an array of required random numbers SRandom(@YEAR + @MON + @MDAY + @HOUR + @MIN + @SEC) Local $aTemp[$iNumElements] _ArrayShuffle($aNumbers) For $i = 0 To $iNumElements - 1 $aTemp[$i] = $aNumbers[$i] Next _ArraySort($aTemp) Return $aTemp EndFunc ;==>_GenerateQuiz Func _ShowControls($aTemp) ; render controls visible (and enabled) $aTemp = _EnforceArray($aTemp) For $i = 0 To UBound($aTemp) - 1 GUICtrlSetState($aTemp[$i], $GUI_SHOW) GUICtrlSetColor($aTemp[$i], $iForeColor) GUICtrlSetBkColor($aTemp[$i], $iBackColor) Next EndFunc ;==>_ShowControls Func _MaskControls($aTemp) ; mask the controls $aTemp = _EnforceArray($aTemp) For $i = 0 To UBound($aTemp) - 1 GUICtrlSetColor($aTemp[$i], $iForeColor) GUICtrlSetBkColor($aTemp[$i], $iForeColor) Next EndFunc ;==>_MaskControls Func _HideControls($aTemp) ; hide the controls (implies disable) $aTemp = _EnforceArray($aTemp) For $i = 0 To UBound($aTemp) - 1 GUICtrlSetState($aTemp[$i], $GUI_HIDE) ; $GUI_DISABLE) ; GUICtrlSetColor($aButtons[$aTemp[$i] - 1], $iBackColor) ; GUICtrlSetBkColor($aButtons[$aTemp[$i] - 1], $iBackColor) Next EndFunc ;==>_HideControls Func _EnforceArray($vParam) ; if only one value is passed, turn it into an array of only 1 element If Not IsArray($vParam) Then Local $aTemp[1] = [$vParam] Return $aTemp EndIf Return $vParam EndFunc ;==>_EnforceArray Func __get_IDs_by_indexes(ByRef $aCtrls, ByRef $aNdxs) ; returns the handles of the controls pointed to by the indexes Local $aTemp[UBound($aNdxs)] For $i = 0 To UBound($aNdxs) - 1 $aTemp[$i] = $aCtrls[$aNdxs[$i] - 1] Next Return $aTemp EndFunc ;==>__get_IDs_by_indexes Func _EndOfGame() ; _WinAPI_PlaySound ("SystemExit" , Null, $SND_ALIAS) GUIDelete() Exit EndFunc ;==>_EndOfGame P.S. At this link (https://web.archive.org/web/20131006161544/http://games.lumosity.com/chimp.html) there is a Flash version of this game.
    • By Barney
      From MiniMax to Machine Learning ... Tic Tac Toe is a good game for studying AI algorithm because it's simple!
      I use Tabular Q Learning to implement this game, Every time a game finished, it will use the Q function to update
      the score of each steps it played.
      Q(S,A) = Q(S,A) + α ∗ (γ ∗ maxaQ(S′,a) − Q(S,A))
      S being the current state, A the current action, S′ the state after doing A, α being the learning rate, γ being the
      discount factor,  and maxaQ(S′,a) the highest Q value of any move in the next state S′, i.e. the Q value of the best
      move in the following state.
      It's funny to see that it plays better and better. That's why people were charmed by Machine Learning!
      Thank you!
      Download: tic_tac_toe.zip

    • By Dan_555
      Hi, this is a Nonogram Game.
      It is compiled for windows in 32bit (64bit does not work as intended!), sourcecode in v3.3.14.5, icon and the required ini file with more than 100 puzzles.
      The Game has an built-in Editor, and can generate random playfields. 
    • By gwinter
      Just something I made to auto-collect Gil from FFCC and to test out a new templating system for AutoIt. The templating system is a work in progress, but it is meant to be a companion to AutoIT, which automates creation of GUI, buttons, scripts, templates, etc. It also has built-in chat and group-collaboration, an asset management system and online library for resources.
      -snip-
    • By n0ktar
      is it possible to make a wall chams in rainbow six siege using autoit scripts? tell me please and how . 
×
×
  • Create New...