rem ================================================================== rem FIRE - Four In Row Extreme(ly lousy) rem rem By (drunk) Marcus. rem ================================================================== visible: rem Constants. PLY = 1 COM = 2 rem Tils size of game field. X_MAX = 7 Y_MAX = 7 vGrid[X_MAX][Y_MAX] BACKGROUND_IMAGE = 0 PIECES_IMAGE = 1 hidden: rem Load fonts and images. if javac() load font 0, "arial20.txt", "arial20.png" load image PIECES_IMAGE, "bricks.png" else load font 0, "arial20.txt", "arial20.bmp" load image PIECES_IMAGE, "bricks.bmp" endif load image BACKGROUND_IMAGE, "background.bmp" rem Bricks contains two cels: player's piece and computer's piece. set image grid PIECES_IMAGE, 2, 1 rem Set window and turn off automatic redraw. set window 16, 16, X_MAX*32, Y_MAX*32 + 32 set redraw off proc ClearGrid rem Main loop. do rem Get mouse position and scale to grid. xg = mousex()/32 yg = mousey()/32 rem Player move's by clicking. if mousebutton(0, true) rem Inside grid? if xg >= 0 and xg < X_MAX rem Any space left in col? if vGrid[xg][0] = 0 rem Find empty spot. for y = 0 to Y_MAX - 2 if vGrid[xg][y + 1] <> 0 then break next rem Let piece fall down and stay there. proc PieceFall PLY, xg, y vGrid[xg][y] = PLY rem Redraw grid and wait a tick. proc DrawGrid redraw wait 250 rem Has Player won? if IsWinner(PLY) proc ShowResult "Player Wins!" proc ClearGrid else rem Is the game field full? if IsFull() proc ShowResult "No winner!" proc ClearGrid else rem Let computer make a move. proc ComputerMove proc DrawGrid redraw rem Has computer won? if IsWinner(COM) proc ShowResult "Computer Wins!" proc ClearGrid elseif IsFull() proc ShowResult "No winner!" proc ClearGrid endif endif endif endif endif endif proc DrawGrid rem Draw marker. set color 255, 255, 255, 128 draw rect (mousex()/32)*32, (mousey()/32)*32, 32, 32, true rem It's always player's move when here. set color 255, 255, 255, 128 set caret 112, 228 center "Player's Move" redraw wait 10 until not running() or keydown(27) end rem ================================================================== rem Animate piece falling down. rem ================================================================== procedure PieceFall(id, x, dsty) y = -32 while y < dsty*32 proc DrawGrid set color 255, 255, 255 draw image PIECES_IMAGE, x*32, y, id - 1 set color 255, 255, 255, 128 set caret 112, 228 if id = COM center "Computer's Move" else center "Player's Move" endif redraw wait 10 y = y + 8 wend endproc rem ================================================================== rem Show result. rem ================================================================== procedure ShowResult(txt$) set color 0, 0, 0, 128 cls set color 255, 255, 255 set caret 112, 228 center txt$ redraw wait mousebutton endproc rem ================================================================== rem Clear grid. rem ================================================================== procedure ClearGrid() randomize time() for y = 0 to Y_MAX - 1 for x = 0 to X_MAX - 1 vGrid[x][y] = 0 next next endproc rem ================================================================== rem Draw grid. rem ================================================================== procedure DrawGrid() set color 255, 255, 255 draw image BACKGROUND_IMAGE, 0, 0 for y = 0 to Y_MAX - 1 for x = 0 to X_MAX - 1 if vGrid[x][y] > 0 then draw image PIECES_IMAGE, x*32, y *32, vGrid[x][y] - 1 next next endproc rem ================================================================== rem Let computer make a move. rem ================================================================== procedure ComputerMove() rem Calculate current value of game field for computer and player. orgVal = EvaluateGrid(COM) orgPlyVal = EvaluateGrid(PLY) maxVal = 0 posX = 0 posY = 0 rem Look for the move that brings the greatest increase in value rem for computer OR player. If the player would make a certain rem move that gave much increase, the computer should of course rem prevent that move by putting it's on piece there. valCount = 0 for x = 0 to X_MAX - 1 if vGrid[x][0] = 0 for y = 0 to Y_MAX - 2 if vGrid[x][y + 1] <> 0 then break next valcom = ComputerMoveXY(x, y) - orgVal valply = PlayerMoveXY(x, y) - orgPlyVal val = max(valcom, valply) if val > maxVal maxVal = val posX = x posY = y valCount = 1 elseif val = maxVal valCount = valCount + 1 if rnd(valCount) = 0 maxVal = val posX = x posY = y endif endif endif next proc PieceFall COM, posX, posY vGrid[posX][posY] = COM endproc rem ================================================================== rem Return value of field for computer move. rem ================================================================== function ComputerMoveXY(x, y) oldcom = EvaluateGrid(COM) vGrid[x][y] = COM if IsWinner(COM) vGrid[x][y] = 0 return 6356500 endif value = EvaluateGrid(COM) if y > 0 oldply = EvaluateGrid(PLY) vGrid[x][y - 1] = PLY if IsWinner(PLY) vGrid[x][y - 1] = 0 vGrid[x][y] = 0 return 0 endif newply = EvaluateGrid(PLY) vGrid[x][y - 1] = 0 if newply - oldply >= value - oldcom then value = 0 endif vGrid[x][y] = 0 return value endfunc rem ================================================================== rem Return value of field for player move. rem ================================================================== function PlayerMoveXY(x, y) vGrid[x][y] = PLY if IsWinner(PLY) vGrid[x][y] = 0 return 6356400 endif if y > 0 vGrid[x][y - 1] = PLY if IsWinner(PLY) vGrid[x][y] = 0 vGrid[x][y - 1] = 0 return 0 endif vGrid[x][y - 1] = 0 endif value = EvaluateGrid(PLY) vGrid[x][y] = 0 return value endfunc rem ================================================================== rem Return true if id (PLY or COM) has won. rem ================================================================== function IsWinner(id) win = false for y = 0 to Y_MAX - 1 for x = 0 to X_MAX - 1 if EvaluateWinRec(id, x, y, -1, 0, 0) + EvaluateWinRec(id, x, y, 1, 0, 0) - 1 >= 4 then win = true if EvaluateWinRec(id, x, y, 0, -1, 0) + EvaluateWinRec(id, x, y, 0, 1, 0) - 1 >= 4 then win = true if EvaluateWinRec(id, x, y, -1, -1, 0) + EvaluateWinRec(id, x, y, 1, 1, 0) - 1 >= 4 then win = true if EvaluateWinRec(id, x, y, 1, - 1, 0) + EvaluateWinRec(id, x, y, -1, 1, 0) - 1 >= 4 then win = true if win then break next if win then break next return win endfunc rem ================================================================== rem Recursive function for finding a winner. rem ================================================================== function EvaluateWinRec(id, x, y, dx, dy, value) if x < 0 then return value if x >= X_MAX then return value if y < 0 then return value if y >= Y_MAX then return value if vGrid[x][y] = 0 then return value if vGrid[x][y] <> id then return value value = value + 1 return EvaluateWinRec(id, x + dx, y + dy, dx, dy, value); endfunc rem ================================================================== rem Return true if game field is full. rem ================================================================== function IsFull() full = true for x = 0 to X_MAX - 1 if vGrid[x][0] = 0 full = false break endif next return full endfunc rem ================================================================== rem Calculate value of game field for id (PLY or COM). rem ================================================================== function EvaluateGrid(id) val = 0 for y = 0 to Y_MAX - 1 for x = 0 to X_MAX - 1 lr = EvaluateRec(id, x, y, -1, 0, 1) + EvaluateRec(id, x, y, 1, 0, 1) - 1 ud = EvaluateRec(id, x, y, 0, -1, 1) + EvaluateRec(id, x, y, 0, 1, 1) - 1 lurd = EvaluateRec(id, x, y, -1, -1, 1) + EvaluateRec(id, x, y, 1, 1, 1) - 1 ruld = EvaluateRec(id, x, y, 1, - 1, 1) + EvaluateRec(id, x, y, -1, 1, 1) - 1 val = val + lr + ud + lurd + ruld next next return val endfunc rem ================================================================== rem Recursive function for calculating value of game field. rem ================================================================== function EvaluateRec(id, x, y, dx, dy, value) if x < 0 then return value if x >= X_MAX then return value if y < 0 then return value if y >= Y_MAX then return value if vGrid[x][y] = 0 then return value if vGrid[x][y] <> id then return value value = value *2 return EvaluateRec(id, x + dx, y + dy, dx, dy, value); endfunc