using System; using System.Collections.Generic; namespace TicTacToe { public class AIPlayer { private Game game; private Game.SquareState mySymbol; private Game.SquareState opponentSymbol; public AIPlayer(Game game, Game.SquareState mySymbol) { this.game = game; this.mySymbol = mySymbol; opponentSymbol = (mySymbol == Game.SquareState.X) ? Game.SquareState.O : Game.SquareState.X; } public (int, int) MakeMove() { (int, int) bestMove = (-1, -1); int bestScore = Int32.MinValue; foreach ((int x, int y) in game.GetAvailableMoves()) { game.MakeMove(x, y, mySymbol); int score = Minimax(game, 0, false); game.MakeMove(x, y, Game.SquareState.Empty); // undo move if (score > bestScore) { bestScore = score; bestMove = (x, y); } } return bestMove; } private int Minimax(Game game, int depth, bool isMaximizing) { if (game.CheckForWinner()) { return isMaximizing ? -1 : 1; } if (game.IsBoardFull()) { return 0; } if (isMaximizing) { int maxScore = Int32.MinValue; foreach ((int x, int y) in game.GetAvailableMoves()) { game.MakeMove(x, y, mySymbol); int score = Minimax(game, depth + 1, false); game.MakeMove(x, y, Game.SquareState.Empty); // undo move maxScore = Math.Max(maxScore, score); } return maxScore; } else { int minScore = Int32.MaxValue; foreach ((int x, int y) in game.GetAvailableMoves()) { game.MakeMove(x, y, opponentSymbol); int score = Minimax(game, depth + 1, true); game.MakeMove(x, y, Game.SquareState.Empty); // undo move minScore = Math.Min(minScore, score); } return minScore; } } } }