Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Mini Checkers
#1
MINI CHECKERS

How to play :
-Click on your black piece
 Click on a valid square to move
 Move your piece 1 square diagonally forward
 No backward movement – pieces never become "kings"
-If captures exist, you can only select pieces that can capture
 Captured piece is removed immediately

Reference :
Basic checkers game board by Marcus
https://www.naalaa.com/forum/thread-74-p...tml#pid466



Code:
'===============================================================
'MINI CHECKERS
'
'How to play :
'-Click on your black piece
' Click on a valid square to move
' Move your piece 1 square diagonally forward
' No backward movement – pieces never become "kings"
'-If captures exist, you can only select pieces that can capture
' Captured piece is removed immediately
'
'Reference :
'Basic checkers game board by Marcus
'https://www.naalaa.com/forum/thread-74-post-466.html#pid466
'===============================================================



set window "Mini Checkers", 640, 480
set redraw off


'----------------
' Initialization
'----------------

constant GRID = 4
constant SQUARE = 53

visible board = fill(0, GRID, GRID)
visible gameOver = 0
visible winner = 0          ' 0 = draw, 1 = computer wins, 2 = player wins
visible turn = 2            ' player 2 (you) starts first game
visible computerTurn = 0
visible holding = 0
visible origX = 0
visible origY = 0
visible nextStarter = 1     ' Toggle starter on next restart (starts with 1 after first game)

boardX = (width(primary) - GRID*SQUARE)/2
boardY = (height(primary) - GRID*SQUARE)/2

' place pieces
for x = 0 to GRID - 1
    if (0 + x) % 2 = 1 then board[x][0] = 1
next
for x = 0 to GRID - 1
    if (3 + x) % 2 = 1 then board[x][3] = 2
next


'------------
' Functions
'------------
function DrawPiece(player, x, y)
    if player = 2 then
        set color 32, 32, 32
    else
        set color 240, 240, 240
    endif
    draw ellipse x, y, SQUARE/2 - 4, SQUARE/2 - 4, true
    set color 0, 0, 0
    draw ellipse x, y, SQUARE/2 - 4, SQUARE/2 - 4, false
endfunc

function ValidMove(player, fx, fy, tx, ty)
    if tx < 0 or tx >= GRID or ty < 0 or ty >= GRID then return 0
    if board[tx][ty] <> 0 then return 0
   
    ' Regular move: one diagonal square forward
    if abs(tx - fx) = 1 and abs(ty - fy) = 1
        if player = 1 and ty > fy then return 1 ' computer moves down
        if player = 2 and ty < fy then return 1 ' human moves up
    endif
   
    ' Capture move: jump two squares diagonally over opponent
    if abs(tx - fx) = 2 and abs(ty - fy) = 2
        cx = (fx + tx)/2
        cy = (fy + ty)/2
        if board[cx][cy] <> 0 and board[cx][cy] <> player
            if player = 1 and ty > fy then return 1 ' computer captures down
            if player = 2 and ty < fy then return 1 ' human captures up
        endif
    endif
   
    return 0
endfunc

function HasCapture(player)
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            if board[x][y] = player
                if ValidMove(player, x, y, x - 2, y - 2) then return 1
                if ValidMove(player, x, y, x + 2, y - 2) then return 1
                if ValidMove(player, x, y, x - 2, y + 2) then return 1
                if ValidMove(player, x, y, x + 2, y + 2) then return 1
            endif
        next
    next
    return 0
endfunc

' Check if player has ANY valid move (regular or capture)
function HasAnyMove(player)
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            if board[x][y] = player
                ' Check all 4 diagonal directions for regular moves
                if ValidMove(player, x, y, x - 1, y - 1) then return 1
                if ValidMove(player, x, y, x + 1, y - 1) then return 1
                if ValidMove(player, x, y, x - 1, y + 1) then return 1
                if ValidMove(player, x, y, x + 1, y + 1) then return 1
               
                ' Check all 4 diagonal directions for captures
                if ValidMove(player, x, y, x - 2, y - 2) then return 1
                if ValidMove(player, x, y, x + 2, y - 2) then return 1
                if ValidMove(player, x, y, x - 2, y + 2) then return 1
                if ValidMove(player, x, y, x + 2, y + 2) then return 1
            endif
        next
    next
    return 0
endfunc

function CheckWin()
    p1count = 0
    p2count = 0
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            if board[x][y] = 1 then p1count = p1count + 1
            if board[x][y] = 2 then p2count = p2count + 1
        next
    next
   
    if p1count = 0 then
        winner = 2
        return 1
    endif
    if p2count = 0 then
        winner = 1
        return 1
    endif
    return 0
endfunc

' detection
function CheckStalemate()
    ' First ensure both players still have pieces (win condition takes priority)
    p1count = 0
    p2count = 0
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            if board[x][y] = 1 then p1count = p1count + 1
            if board[x][y] = 2 then p2count = p2count + 1
        next
    next
   
    if p1count = 0 or p2count = 0 then return 0  ' Win/loss already handled
   
    ' Stalemate: current player has pieces but NO legal moves
    if HasAnyMove(turn) = 0 then
        winner = 0  ' 0 = draw
        return 1
    endif
   
    return 0
endfunc

function ComputerMove()
    ' First check for captures (mandatory)
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            if board[x][y] = 1
                ' Try left capture
                if ValidMove(1, x, y, x - 2, y + 2)
                    board[x][y] = 0
                    board[x - 1][y + 1] = 0 ' remove captured piece
                    board[x - 2][y + 2] = 1
                    return
                endif
                ' Try right capture
                if ValidMove(1, x, y, x + 2, y + 2)
                    board[x][y] = 0
                    board[x + 1][y + 1] = 0 ' remove captured piece
                    board[x + 2][y + 2] = 1
                    return
                endif
            endif
        next
    next
   
    ' No captures available, make regular move
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            if board[x][y] = 1
                if ValidMove(1, x, y, x - 1, y + 1)
                    board[x][y] = 0
                    board[x - 1][y + 1] = 1
                    return
                endif
                if ValidMove(1, x, y, x + 1, y + 1)
                    board[x][y] = 0
                    board[x + 1][y + 1] = 1
                    return
                endif
            endif
        next
    next
endfunc

function RestartGame()
    board = fill(0, GRID, GRID)
    for x = 0 to GRID - 1
        if (0 + x) % 2 = 1 then board[x][0] = 1
    next
    for x = 0 to GRID - 1
        if (3 + x) % 2 = 1 then board[x][3] = 2
    next
   
    ' Alternate starting player on each restart
    turn = nextStarter
    nextStarter = 3 - nextStarter  ' Toggle between 1 and 2 (3-1=2, 3-2=1)
   
    gameOver = 0
    winner = 0
    holding = 0
   
    'Trigger computer move immediately if it's computer's turn
    if turn = 1 then
        computerTurn = 1
    else
        computerTurn = 0
    endif
endfunc


'------------
' Main Loop
'------------
while not keydown(KEY_ESCAPE, true)
    if gameOver = 1
        ' Allow restart on SPACE, ENTER, or mouse click
        if keydown(KEY_SPACE, true) or keydown(KEY_RETURN, true) or mousebutton(0, true) then
            RestartGame()
        endif
    else
        mx = mousex()
        my = mousey()
        gx = int((mx - boardX)/SQUARE)
        gy = int((my - boardY)/SQUARE)
       
        ' human move
        if turn = 2 and mx >= boardX and mx < boardX + GRID*SQUARE and
        my >= boardY and my < boardY + GRID*SQUARE
            if mousebutton(0, true)
                if holding = 0
                    if board[gx][gy] = 2
                        mustCapture = HasCapture(2)
                        canCapture = ValidMove(2, gx, gy, gx - 2, gy - 2) or
                        ValidMove(2, gx, gy, gx + 2, gy - 2)
                       
                        ' Only allow selection if piece can move
                        if (not mustCapture) or canCapture
                            holding = 2
                            origX = gx
                            origY = gy
                            board[gx][gy] = 0
                        endif
                    endif
                else
                    if ValidMove(2, origX, origY, gx, gy)
                        ' Check if this is a capture move
                        if abs(gx - origX) = 2 and abs(gy - origY) = 2
                            cx = (origX + gx)/2
                            cy = (origY + gy)/2
                            board[cx][cy] = 0
                        endif
                       
                        board[gx][gy] = 2
                       
                        ' After human move: check win ? check stalemate ? switch turn
                        if CheckWin() then
                            gameOver = 1
                        elseif CheckStalemate() then
                            gameOver = 1
                        else
                            turn = 1
                            computerTurn = 1  ' Schedule computer's turn
                        endif
                    else
                        ' Return piece to original position
                        board[origX][origY] = 2
                    endif
                    holding = 0
                endif
            endif
        endif
       
        ' computer move
        if computerTurn = 1
            wait 800
            ComputerMove()
           
            ' After computer move: check win ? check stalemate ? switch turn
            if CheckWin() then
                gameOver = 1
            elseif CheckStalemate() then
                gameOver = 1
            else
                turn = 2  ' Switch back to player
            endif
            computerTurn = 0
        endif
    endif
   
    ' draw board
    set color 0, 0, 0
    cls
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            if (y + x) % 2 = 1 then
                set color 255, 204, 0
            else
                set color 255, 153, 0
            endif
            draw rect boardX + x*SQUARE, boardY + y*SQUARE, SQUARE, SQUARE, true
            if board[x][y] <> 0 then
                DrawPiece(board[x][y], boardX + (x + 0.5)*SQUARE, boardY + (y + 0.5)*SQUARE)
            endif
        next
    next
    if holding <> 0 then DrawPiece(holding, mx, my)
   
    ' Display turn indicator during gameplay
    if gameOver = 0
        set color 0, 0, 0, 180
        draw rect 0, height(primary) - 60, width(primary), 60, true
       
        set color 255, 255, 255
        if turn = 2 then
            turnText = "YOUR TURN"
        else
            turnText = "COMPUTER'S TURN"
        endif
       
        cx = width(primary)/2 - width(turnText)/2
        set caret cx, height(primary) - 45
        wln turnText
    endif
   
    ' Draw game over message if game over
    if gameOver = 1
        set color 255, 255, 255
        set caret 10,10
       
        ' Display message based on winner value
        if winner = 0 then
            text = "DRAW!"
            wln "No legal moves"
        elseif winner = 1 then
            text = "COMPUTER WINS!"
        else
            text = "YOU WIN!"
        endif
        wln text
               
        ' Write restart instructions
        restartText = "Press SPACE BAR to restart"
        wln restartText
    endif
   
    redraw
    fwait 60
wend
Reply
#2
Cool Big Grin
Logic is the beginning of wisdom.
Reply
#3
It turned out very well and it's a good base to continue with. Smile
Reply
#4
Nice one!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)