public Board.move FindBestMove(char[,] board, char player) { List <Board.move> bestMoveList = new List <Board.move>(); Board.move bestMove = new Board.move(); bestMove.score = -100; for (ushort x = 0; x < 3; x++) { for (ushort y = 0; y < 3; y++) { if (board[x, y] == Board.emptyPosition) { char[,] scenarioBoard = Board.MirorBoard(board); scenarioBoard[x, y] = player; Board.move someMove = new Board.move(); someMove.depth = 0; someMove.x = x; someMove.y = y; someMove.score = Minimax(scenarioBoard, 0, Board.OppositePlayer(player), x, y); if (someMove.score > bestMove.score) { bestMove.x = x; bestMove.y = y; bestMove.score = someMove.score; } ttt.VirtualPrint("[Evaluating] move (" + x + "," + y + ") with score: " + someMove.score); } } } ttt.VirtualPrint("[Selecting] move: (" + bestMove.x + "," + bestMove.y + ") score " + bestMove.score); ttt.VirtualPrint("--------------------------------------"); // TODO: select random of equal score moves once working properly return(bestMove); }
public int Minimax(char[,] board, ushort depth, char player, ushort x, ushort y) { string encodedBoard = Board.Encode(board); if (Board.TerminalState(board, player, x, y)) { int score = GetBoardScore(board, depth, player, x, y); return(score); } Board.move bestMove = new Board.move(); bestMove.depth = depth; depth += 1; if (player == maximizingPlayer) // maximize { bestMove.score = -100; for (ushort xIndex = 0; xIndex < 3; xIndex++) { for (ushort yIndex = 0; yIndex < 3; yIndex++) { if (board[xIndex, yIndex] == Board.emptyPosition) { char[,] subBoard = Board.MirorBoard(board); subBoard[xIndex, yIndex] = Board.OppositePlayer(player); string subEncoded = Board.Encode(subBoard); int score = Minimax(subBoard, depth, Board.OppositePlayer(player), xIndex, yIndex); if (score > bestMove.score) { bestMove.score = score; bestMove.x = xIndex; bestMove.y = yIndex; } } } } } else // minimize { bestMove.score = 100; for (ushort xIndex = 0; xIndex < 3; xIndex++) { for (ushort yIndex = 0; yIndex < 3; yIndex++) { if (board[xIndex, yIndex] == Board.emptyPosition) { char[,] subBoard = Board.MirorBoard(board); subBoard[xIndex, yIndex] = Board.OppositePlayer(player); string subEncoded = Board.Encode(subBoard); int score = Minimax(subBoard, depth, Board.OppositePlayer(player), xIndex, yIndex); if (score < bestMove.score) { bestMove.score = score; bestMove.x = xIndex; bestMove.y = yIndex; } } } } } return(bestMove.score); }
// Update is called once per frame void Update() { if (currentPlayer != '_') // game is waiting { if (currentPlayer == computer) { Board.move nextMove = minmax.FindBestMove(gameBoard, currentPlayer); gameBoard[nextMove.x, nextMove.y] = currentPlayer; peices.Add(Instantiate(oPeice, transform)); peices[peices.Count - 1].transform.position = physicalBoard[nextMove.x, nextMove.y].transform.position + new Vector3(0, 5, -2); if (Board.TerminalState(gameBoard, currentPlayer, nextMove.x, nextMove.y)) { if (Board.GetWinner(gameBoard, currentPlayer, nextMove.x, nextMove.x) == computer) { VirtualPrint("The winner is the human"); } else { VirtualPrint("The winner is nobody"); } currentPlayer = Board.emptyPosition; } else { currentPlayer = Board.OppositePlayer(currentPlayer); } //VirtualPrint(Board.Visualize(gameBoard)); } else if (Input.GetMouseButtonDown(0)) { RaycastHit hit; Ray ray = playerCamera.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit)) { for (ushort x = 0; x < 3; x++) { for (ushort y = 0; y < 3; y++) { if (physicalBoard[x, y] == hit.transform.gameObject) { moveX = x; moveY = y; break; } } } } if (Board.IsValidMove(gameBoard, currentPlayer, moveX, moveY)) { peices.Add(Instantiate(xPeice, transform)); peices[peices.Count - 1].transform.position = physicalBoard[moveX, moveY].transform.position + new Vector3(0, 5, 0); gameBoard[moveX, moveY] = currentPlayer; if (Board.TerminalState(gameBoard, currentPlayer, moveX, moveY)) { if (Board.GetWinner(gameBoard, currentPlayer, moveX, moveY) == human) { VirtualPrint("The winner is the human"); } else { VirtualPrint("The winner is nobody"); } currentPlayer = Board.emptyPosition; } else { currentPlayer = Board.OppositePlayer(currentPlayer); } //VirtualPrint(Board.Visualize(gameBoard)); } } } if (Input.GetMouseButtonDown(0)) { RaycastHit hit; Ray ray = playerCamera.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit)) { if (reset == hit.transform.gameObject) { StartNewGame(); moveX = 5; } } } }