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

How to play:
 - Click on a valid square to place your piece (black)
 - Your move must flip opponent pieces
 - If you have no valid moves, turn passes to opponent
 - Most pieces wins!

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

Code:
'===============================================================
'MINI REVERSI
'
'How to play:
' - Click on a valid square to place your piece (black)
' - Your move must flip opponent pieces
' - If you have no valid moves, turn passes to opponent
' - Most pieces wins!
'
'Reference:
'Basic game board by Marcus
'https://www.naalaa.com/forum/thread-74-post-466.html#pid466 
'===============================================================

#win32
set window "Mini Reversi", 640, 480
set redraw off

'----------------
' Initialization
'----------------
constant GRID = 4
constant SQUARE = 53

visible board = fill(0, GRID, GRID)
board.x = (width(primary) - GRID*SQUARE)/2
board.y = (height(primary) - GRID*SQUARE)/2

visible gameOver = 0
visible winner = 0          ' 0 = draw, 1 = computer wins, 2 = player wins
visible turn = 0            ' 1 = computer (white), 2 = player (black)
visible nextStarter = 1     ' who starts the game
visible computerDelay = 0   ' Frames until computer moves
visible passTimer = 0       ' Frames to show "Pass" message

' Initialize game state
RestartGame()

'------------
' Functions
'------------
function DrawPiece(player, x, y)
    if player = 2 set color 32, 32, 32      ' Black for player
    if player = 1 set color 240, 240, 240   ' White for computer
    draw ellipse x, y, SQUARE/2 - 4, SQUARE/2 - 4, true
endfunc

function ValidMove(player, x, y)
    ' Check bounds and empty square
    if x < 0 or x >= GRID or y < 0 or y >= GRID then return 0
    if board[x][y] <> 0 then return 0
   
    opponent = 3 - player
    ' Check all 8 directions
    for dx = -1 to 1
        for dy = -1 to 1
            ' Skip center direction (0,0)
            if dx <> 0 or dy <> 0 then
                cx = x + dx
                cy = y + dy
                ' Must have adjacent opponent piece
                if cx >= 0 and cx < GRID and cy >= 0 and cy < GRID then
                    if board[cx][cy] = opponent then
                        ' Walk in direction to find player's piece
                        do
                            cx = cx + dx
                            cy = cy + dy
                            if cx < 0 or cx >= GRID or cy < 0 or cy >= GRID then break
                            if board[cx][cy] = 0 then break
                            if board[cx][cy] = player then return 1
                        loop
                    endif
                endif
            endif
        next
    next
    return 0
endfunc

function HasAnyMove(player)
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            if board[x][y] = 0 if ValidMove(player, x, y) = 1 return 1
        next
    next
    return 0
endfunc

function FlipCaptures(player, x, y)
    opponent = 3 - player
    for dx = -1 to 1
        for dy = -1 to 1
            ' Skip center direction (0,0)
            if dx <> 0 or dy <> 0 then
                cx = x + dx
                cy = y + dy
                if cx >= 0 and cx < GRID and cy >= 0 and cy < GRID then
                    if board[cx][cy] = opponent then
                        ' Find end of capture line
                        ex = cx
                        ey = cy
                        do
                            ex = ex + dx
                            ey = ey + dy
                            if ex < 0 or ex >= GRID or ey < 0 or ey >= GRID then break
                            if board[ex][ey] = 0 then break
                            if board[ex][ey] = player then
                                ' Flip all pieces in between
                                fx = cx
                                fy = cy
                                while fx <> ex or fy <> ey
                                    board[fx][fy] = player
                                    fx = fx + dx
                                    fy = fy + dy
                                wend
                                break
                            endif
                        loop
                    endif
                endif
            endif
        next
    next
endfunc

function ComputerMove()
    ' Count all valid moves first
    moveCount = 0
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            if board[x][y] = 0 if ValidMove(1, x, y) = 1 moveCount = moveCount + 1
        next
    next
   
    ' No valid moves? Game logic will handle passing
    if moveCount = 0 then return
   
    ' Pick a random move index
    targetIndex = rnd(moveCount)
    currentIndex = 0
   
    ' Find and play that random move
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            if board[x][y] = 0 then
                if ValidMove(1, x, y) = 1 then
                    if currentIndex = targetIndex then
                        board[x][y] = 1
                        FlipCaptures(1, x, y)
                        return
                    endif
                    currentIndex = currentIndex + 1
                endif
            endif
        next
    next
endfunc

function CheckWin()
    count1 = 0
    count2 = 0
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            if board[x][y] = 1 then count1 = count1 + 1
            if board[x][y] = 2 then count2 = count2 + 1
        next
    next
   
    if count1 > count2 then
        winner = 1
    elseif count2 > count1 then
        winner = 2
    else
        winner = 0
    endif
endfunc

function ProcessAfterMove()
    ' Switch to opponent's turn
    turn = 3 - turn
   
    ' Check if opponent has moves
    if HasAnyMove(turn) = 0 then
        ' Opponent can't move - check if current player can move
        if HasAnyMove(3 - turn) = 0 then
            ' Both players stuck - game over
            gameOver = 1
            CheckWin()
        else
            ' Pass turn back to current player
            turn = 3 - turn
            passTimer = 60  ' Show "Pass" message for 1 second
        endif
    endif
endfunc

function RestartGame()
    ' Clear board
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            board[x][y] = 0
        next
    next
   
    ' Setup initial pieces (standard 6x6 start)
    board[1][1] = 1  ' Computer (white)
    board[2][2] = 1
    board[1][2] = 2  ' Player (black)
    board[2][1] = 2
   
    gameOver = 0
    winner = 0
    passTimer = 0
   
    ' Alternate starting player each game
    turn = nextStarter
    nextStarter = 3 - nextStarter
   
    ' Schedule computer move if it starts
    if turn = 1 then
        computerDelay = 30
    else
        computerDelay = 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 - board.x)/SQUARE)
        gy = int((my - board.y)/SQUARE)
       
        ' Human move (player is black = 2)
        if turn = 2 and mousebutton(0, true) then
            if gx >= 0 and gx < GRID and gy >= 0 and gy < GRID then
                if board[gx][gy] = 0 then
                    if ValidMove(2, gx, gy) = 1 then
                        board[gx][gy] = 2
                        FlipCaptures(2, gx, gy)
                        ProcessAfterMove()
                        ' Schedule computer move if it's their turn
                        if turn = 1 and gameOver = 0 computerDelay = 30
                    endif
                endif
            endif
        endif
       
        ' Computer move delay handling
        if computerDelay > 0 then
            computerDelay = computerDelay - 1
            if computerDelay = 0 and turn = 1 and gameOver = 0 then
                ComputerMove()
                ProcessAfterMove()
                ' Schedule next move if computer gets another turn (after pass)
                if turn = 1 and gameOver = 0 computerDelay = 130
            endif
        endif
    endif
   
    ' clear screen
    set color 0, 0, 0; cls
   
    ' Draw board squares
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            if (y + x) % 2 = 1 then
                set color 0, 200, 0
            else
                set color 0, 180, 0
            endif
            draw rect board.x + x*SQUARE, board.y + y*SQUARE, SQUARE, SQUARE, true     
        next
    next
   
    ' Draw pieces from board state
    for y = 0 to GRID - 1
        for x = 0 to GRID - 1
            p = board[x][y]
            if p <> 0 then DrawPiece(p, board.x + (x + 0.5)*SQUARE, board.y + (y + 0.5)*SQUARE)
        next
    next
   
    set color 255,255,255 'white
   
    ' during gameplay
    if gameOver = 0 then
        count1 = 0
        count2 = 0
        for y = 0 to GRID - 1
            for x = 0 to GRID - 1
                if board[x][y] = 1 then count1 = count1 + 1
                if board[x][y] = 2 then count2 = count2 + 1
            next
        next
       
        ' whose turn
        set caret width()/2, height()-70
        if turn = 2 then
            center "Your turn (Black Piece)"
        else
            center "Computer thinking..."
            wait 50
        endif
    endif
   
    ' pass
    set caret width()/2, height()-50
    if passTimer > 0 then
        center "PASS"
        passTimer = passTimer - 1
    endif
   
    ' game over
    set caret width()/2,height()-100
    if gameOver = 1 then
        if winner = 2 then
            center "You win!"
        elseif winner = 1 then
            center "Computer wins!"
        else
            center "Draw!"
        endif
        center "Press SPACE BAR to restart"
    endif
   
    redraw
    fwait 60
wend
Reply
#2
I cannot remember the number of times that I played this type of game over the decades... Never gets old... Of course, I enlarged your game to cater to an 8x8 board... It's only fair that I give the computer a chance... lol

Very nice indeed... Big Grin
Logic is the beginning of wisdom.
Reply
#3
Really good - many thanks for sharing....
Reply
#4
I like it. Smile
It turned out very well.
Reply
#5
oh i played that on first cell phone i have
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)