/// <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);
            }
        }
        private void Simulate()
        {
            Player player1; //Player doing this move
            Player player2; //Player next in turn

            if (turn % 2 == 0)
            {
                //P1 move
                player1 = p1;
                player2 = p2;
            }
            else
            {
                //P2 move
                player1 = p2;
                player2 = p1;
            }

            List <ICommand> moves = board.PossibleMoves(player1);

            int      bestScore = int.MinValue;
            ICommand bestMove  = null;

            foreach (ICommand move in moves)
            {
                Board afterMove = board.Copy();
                gameExecutor.ExecuteCommand(afterMove, move);
                int score = 0;
                if (UseAlphaBeta)
                {
                    score = AlphaBeta(afterMove, 1, player1, player2, int.MinValue, int.MaxValue);
                }
                else
                {
                    score = Minimax(afterMove, 1, player1, player2);
                }

                if (score > bestScore)
                {
                    bestScore = score;
                    bestMove  = move;
                }
            }

            if (bestMove != null)
            {
                gameExecutor.ExecuteCommand(bestMove);
            }
            else
            {
                Debug.Log("No possible moves. Game has ended.");
            }

            turn++;
        }
Пример #3
0
        /// <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);
            }
        }