Collaborama About Help Contact Anonymous [login] Source: site.view [edit] Function name: makeTicTacToeMove Arguments: board,turns,playerIs,playerMove,gameLevel Description: Make a tic tac toe move. If playerMove specified, move that and then do a computer move. If playerMove = "?", just do computer move. If playerMove = nil, reset board. Page type: webl Render function: Module: global Page source: var computerIs; if (playerIs == "O") then computerIs = "X" else computerIs = "O" end; var mode = "Playing"; var computerShouldMove = true; var grid; var makeMove = fun (grid, move, piece) var r = move[0]; var c = move[1]; var newRow = grid[r]; if (c == 0) then newRow = [ piece, grid[r][1], grid[r][2] ] elsif (c == 1) then newRow = [ grid[r][0], piece, grid[r][2] ] else newRow = [ grid[r][0], grid[r][1], piece ] end; if (r == 0) then return [ newRow, grid[1], grid[2] ] elsif (r == 1) then return [ grid[0], newRow, grid[2] ] else return [ grid[0], grid[1], newRow ] end; return grid end; var checkWinner = fun (grid) // Horizontal if (grid[0][0] != "?") and (grid[0][0] == grid[0][1]) and (grid[0][1] == grid[0][2]) then return grid[0][0] elsif (grid[1][0] != "?") and (grid[1][0] == grid[1][1]) and (grid[1][1] == grid[1][2]) then return grid[1][0] elsif (grid[2][0] != "?") and (grid[2][0] == grid[2][1]) and (grid[2][1] == grid[2][2]) then return grid[2][0] // Vertical elsif (grid[0][0] != "?") and (grid[0][0] == grid[1][0]) and (grid[1][0] == grid[2][0]) then return grid[0][0] elsif (grid[0][1] != "?") and (grid[0][1] == grid[1][1]) and (grid[1][1] == grid[2][1]) then return grid[0][1] elsif (grid[0][2] != "?") and (grid[0][2] == grid[1][2]) and (grid[1][2] == grid[2][2]) then return grid[0][2] // Diagonal elsif (grid[0][0] != "?") and (grid[0][0] == grid[1][1]) and (grid[1][1] == grid[2][2]) then return grid[0][0] elsif (grid[2][0] != "?") and (grid[2][0] == grid[1][1]) and (grid[1][1] == grid[0][2]) then return grid[2][0] end; return "?" end; var movesLeft = fun (grid) var res = []; var i = 0; var j = 0; while (i < 3) do j = 0; while (j < 3) do if grid[i][j] == "?" then res = res + [ [i, j] ] end; j = j + 1 end; i = i + 1; end; return res end; var pieceAt = fun (row, col, piecePositions) var pos = ToChar(65 + row) + ToString(col+1); every pp in piecePositions do if (pp.position == pos) then return pp.piece end end; return "?" end; var makePiecePositions = fun (grid) var piecePositions = []; var i = 0; while (i < 3) do var j = 0; while (j < 3) do if grid[i][j] != "?" then piecePositions = piecePositions + [ [. position = ToChar(65 + i) + ToString(j+1), piece = grid[i][j] .] ]; end; j = j + 1 end; i = i + 1 end; return piecePositions end; var makeGrid = fun (piecePositions) var grid = []; var i = 0; while (i < 3) do var j = 0; var row = []; while (j < 3) do row = row + [pieceAt(i, j, piecePositions)]; j = j + 1 end; grid = grid + [ row ]; i = i + 1 end; return grid end; var textRender = fun (grid) var str = " 1 2 3\n"; str = str + "A " + grid[0][0] + " " + grid[0][1] + " " + grid[0][2] + "\n"; str = str + "B " + grid[1][0] + " " + grid[1][1] + " " + grid[1][2] + "\n"; str = str + "C " + grid[2][0] + " " + grid[2][1] + " " + grid[2][2] + "\n"; return str end; var existsWinningMove = fun (ml) every move in ml do var testGrid = grid; testGrid = makeMove(grid, move, computerIs); if checkWinner(testGrid) != "?" then return move end; testGrid = grid; testGrid = makeMove(grid, move, playerIs); if checkWinner(testGrid) != "?" then return move end end; return nil end; var chooseComputerMove = fun (ml, gameLevel) var move = ml[Wub_RandomInt(Size(ml))]; var gl = ToInt(gameLevel); if gl > 3 then var winningMove = existsWinningMove(ml); if winningMove != nil then move = winningMove elsif Size(ml) == 9 then move = [1,1] elsif Size(ml) == 8 then if grid[1][1] != "?" then var r = Wub_RandomInt(4); move = Select([[0,0],[0,2],[2,0],[2,2]], r, r+1)[0] end end end; return move end; var boardPiecePositions = (board.boardPiecePositions ? []); if (turns == nil) then turns = []; end; grid = makeGrid(boardPiecePositions); var ml = movesLeft(grid); if playerMove != nil and Size(playerMove)==2 then var move = [ ToInt(playerMove[0])-65, ToInt(Select(playerMove,1,2))-1 ]; var position = playerMove; if (move member ml) then grid = makeMove(grid, move, playerIs); turns = turns + [ [. toPiecePosition = [. position = position, piece = playerIs .] .] ]; ml = movesLeft(grid); else board.message := "There's already a piece at that position."; computerShouldMove = false end end; var winner = checkWinner(grid); if winner != "?" then board.message := "You win!"; mode = "Done" elsif playerMove == nil then // reset the board board.message := "OK, let's get started. It's your turn."; elsif ml == [] then board.message := "No moves left -- Draw!"; mode = "Done" elsif computerShouldMove then var move = chooseComputerMove(ml, gameLevel); var position = ToChar(65+move[0]) + ToString(move[1]+1); grid = makeMove(grid, move, computerIs); winner = checkWinner(grid); turns = turns + [ [. toPiecePosition = [. position = position, piece = computerIs .] .] ]; ml = movesLeft(grid); if winner != "?" then board.message := "I beat you this time..."; mode = "Done" elsif ml == [] then board.message := "No moves left -- Draw!"; mode = "Done" else board.textRender := textRender(grid); board.boardPiecePositions := makePiecePositions(grid); board.message := "I moved: " + position; end; end; board.textRender := textRender(grid); board.boardPiecePositions := makePiecePositions(grid); [. turns = turns, board = board, playerIs=playerIs, status = mode, gameLevel = gameLevel .];