/// <summary> /// A helper method for competing two players against each other. /// </summary> /// <param name="xPlayer">The player to act first.</param> /// <param name="oPlayer">The player to act second.</param> /// <returns> /// The square type of the winner, or SquareTypes.N if the game /// was a draw. /// </returns> public static SquareTypes PlayGameToEnd(IPlayer xPlayer, IPlayer oPlayer) { TicTacToeGame game = new TicTacToeGame(); SquareTypes winner = SquareTypes.N; // Play until we have a winner or the game board is full. for (int moveNum = 0; moveNum < 9 && winner == SquareTypes.N; moveNum++) { IPlayer curPlayer; SquareTypes curSquareType; // Determine if it's X's or O's turn to act. if (moveNum % 2 == 0) { curPlayer = xPlayer; curSquareType = SquareTypes.X; } else { curPlayer = oPlayer; curSquareType = SquareTypes.O; } // Get the next move from the current player. var move = curPlayer.GetMove(game.Board); // Check to make sure the player's move is legal. Debug.Assert(game.IsEmpty(move.X, move.Y), "Player tried to make an illegal move!"); // Set the board to the player's move. game.Board[move.X, move.Y] = curSquareType; // Start checking if we have a winner once xPlayer has made // at least 3 moves. if (moveNum > 3) { winner = game.GetWinner(); } } // Return the square type of the winner, or SquareTypes.N if it was a draw. return(winner); }
/// <summary> /// A helper method for competing two players against each other. /// </summary> /// <param name="xPlayer">The player to act first.</param> /// <param name="oPlayer">The player to act second.</param> /// <returns> /// The square type of the winner, or SquareTypes.N if the game /// was a draw. /// </returns> public static SquareTypes PlayGameToEnd(IPlayer xPlayer, IPlayer oPlayer) { TicTacToeGame game = new TicTacToeGame(); SquareTypes winner = SquareTypes.N; // Play until we have a winner or the game board is full. for (int moveNum = 0; moveNum < 9 && winner == SquareTypes.N; moveNum++) { IPlayer curPlayer; SquareTypes curSquareType; // Determine if it's X's or O's turn to act. if (moveNum % 2 == 0) { curPlayer = xPlayer; curSquareType = SquareTypes.X; } else { curPlayer = oPlayer; curSquareType = SquareTypes.O; } // Get the next move from the current player. var move = curPlayer.GetMove(game.Board); // Check to make sure the player's move is legal. Debug.Assert(game.IsEmpty(move.X, move.Y), "Player tried to make an illegal move!"); // Set the board to the player's move. game.Board[move.X, move.Y] = curSquareType; // Start checking if we have a winner once xPlayer has made // at least 3 moves. if(moveNum > 3) winner = game.GetWinner(); } // Return the square type of the winner, or SquareTypes.N if it was a draw. return winner; }
public Move GetMove(SquareTypes[,] board) { TicTacToeGame.GetWinner(board); int moveNum = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i, j] != SquareTypes.N) { moveNum++; } } } //first move is always a corner if (moveNum == 0) { return(new Move(0, 0)); } //second move should be the center if free, else a corner if (moveNum == 1) { if (board[1, 1] == SquareTypes.N) { return(new Move(1, 1)); } return(new Move(0, 0)); } //make a winning move if possible for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i, j] != SquareTypes.N) { continue; } board[i, j] = SquareType; var winner = TicTacToeGame.GetWinner(board); board[i, j] = SquareTypes.N; if (winner == SquareType) { return(new Move(i, j)); } } } //if we can't win, check if there are any moves that we have to make //to prevent ourselves from losing for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i, j] != SquareTypes.N) { continue; } //set the move to the opponent's type board[i, j] = SquareType == SquareTypes.X ? SquareTypes.O : SquareTypes.X; var winner = TicTacToeGame.GetWinner(board); board[i, j] = SquareTypes.N; //if the opponent will win by moving here, move here to block them if (winner != SquareTypes.N) { return(new Move(i, j)); } } } //if we're here, that means we have made at least 1 move already and can't win //nor lose in 1 move, so just make the optimal play which would be to a free //corner that isn't blocked Move move = null; int max = -1; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i, j] != SquareTypes.N) { continue; } board[i, j] = SquareType; int count = 0; for (int m = 0; m < 3; m++) { for (int n = 0; n < 3; n++) { if (board[m, n] != SquareTypes.N) { continue; } board[m, n] = SquareType; var winner = TicTacToeGame.GetWinner(board); board[m, n] = SquareTypes.N; if (winner == SquareType) { count++; } } } board[i, j] = SquareTypes.N; if (count > max) { move = new Move(i, j); max = count; } } } return(move); }