IEnumerator SimulationCoroutine() { while (board.EndState() == false) { Simulate(); yield return(new WaitForEndOfFrame()); } yield return(null); }
/// <summary> /// Minimax with alpha-beta pruning (faster). /// </summary> /// <param name="board">Board of this game</param> /// <param name="depth">Depth of move tree</param> /// <param name="playerFirst">Maximizing player</param> /// <param name="playerSecond">Minimizing</param> /// <param name="alpha">Alpha parameter</param> /// <param name="beta">Beta parameter</param> /// <returns></returns> public int AlphaBeta(Board board, int depth, Player playerFirst, Player playerSecond, int alpha, int beta) { if (board.EndState() == true || depth == simulationDepth) { return(boardEvaluator.Evaluate(board, playerFirst) - boardEvaluator.Evaluate(board, playerSecond)); } if (depth % 2 == 0) { int bestScore = int.MinValue; List <ICommand> moves = board.PossibleMoves(playerFirst); foreach (ICommand move in moves) { Board afterMove = board.Copy(); gameExecutor.ExecuteCommand(afterMove, move); int score = AlphaBeta(afterMove, depth + 1, playerFirst, playerSecond, alpha, beta); bestScore = Mathf.Max(bestScore, score); alpha = Mathf.Max(alpha, bestScore); if (alpha >= beta) { break; } } return(bestScore); } else { int bestScore = int.MaxValue; List <ICommand> moves = board.PossibleMoves(playerSecond); foreach (ICommand move in moves) { Board afterMove = board.Copy(); gameExecutor.ExecuteCommand(afterMove, move); int score = AlphaBeta(afterMove, depth + 1, playerFirst, playerSecond, alpha, beta); bestScore = Mathf.Min(bestScore, score); beta = Mathf.Min(beta, bestScore); if (beta <= alpha) { break; } } return(bestScore); } }
/// <summary> /// Minimax without alpha-beta pruning (slower). /// </summary> /// <param name="board">Board of this game</param> /// <param name="depth">Depth of move tree</param> /// <param name="playerFirst">Maximizing player</param> /// <param name="playerSecond">Minimizing</param> /// <returns></returns> public int Minimax(Board board, int depth, Player playerFirst, Player playerSecond) { if (board.EndState() == true || depth == _simulationDepth) { return(_boardEvaluator.Evaluate(board, playerFirst) - _boardEvaluator.Evaluate(board, playerSecond)); } if (depth % 2 == 0) { int bestScore = int.MinValue; List <ICommand> moves = board.PossibleMoves(playerFirst); foreach (ICommand move in moves) { Board afterMove = board.Copy(); _gameExecutor.ExecuteCommand(afterMove, move); int score = Minimax(afterMove, depth + 1, playerFirst, playerSecond); bestScore = Mathf.Max(bestScore, score); } return(bestScore); } else { int bestScore = int.MaxValue; List <ICommand> moves = board.PossibleMoves(playerSecond); foreach (ICommand move in moves) { Board afterMove = board.Copy(); _gameExecutor.ExecuteCommand(afterMove, move); int score = Minimax(afterMove, depth + 1, playerFirst, playerSecond); bestScore = Mathf.Min(bestScore, score); } return(bestScore); } }