コード例 #1
0
ファイル: Minimax.cs プロジェクト: cococo111111/Reversi
    // The minimax algorithm itself
    private ScoreMovePair minimax(Dictionary <int, PieceState> board, int turn, int maxDepth, int currDepth, int prune, int moveCount)
    {
        // Checks if either at end of game state or as far down in the tree we are suppose to be. If so uses the
        // static evaluation method appropriate for diffulty settings
        if (isGameOver(board) || currDepth == maxDepth)
        {
            if (GameOptions.Instance.SMART)
            {
                if (currDepth % 2 == 0)
                {
                    if (moveCount >= SWITCH_TIME) // If at the end of game try to maximize the number of pieces instead of playing position
                    {
                        return(new ScoreMovePair(-1, unweightedEvaluation(board, (turn))));
                    }
                    else
                    {
                        return(new ScoreMovePair(-1, weightedEvaluation(board, (turn))));
                    }
                }
                else
                {
                    if (moveCount >= SWITCH_TIME) // If at the end of game try to maximize the number of pieces instead of playing position
                    {
                        return(new ScoreMovePair(-1, unweightedEvaluation(board, (turn == 0) ? 1 : 0)));
                    }
                    else
                    {
                        return(new ScoreMovePair(-1, weightedEvaluation(board, (turn == 0) ? 1 : 0))); // uses positional strategy
                    }
                }
            }
            else
            {
                if (maxDepth % 2 == 0)
                {
                    return(new ScoreMovePair(-1, unweightedEvaluation(board, (turn))));
                }
                else
                {
                    return(new ScoreMovePair(-1, unweightedEvaluation(board, (turn == 0) ? 1 : 0)));
                }
            }
        }

        ScoreMovePair best = new ScoreMovePair(-1, 0); // Initialize best move to none

        if (turn == 0)                                 // Turn is AI's
        {
            best.Score = int.MinValue;
        }
        else // Turn is player's
        {
            best.Score = int.MaxValue;
        }
        for (int i = 0; i < 60; i++) // Iterate through board positions
        {
            int id = (turn == 0) ? ordered[i] : reverseOrdered[i];
            // If move not available skip
            if (board[id] != PieceState.NONE || !isViable(board, id, turn))
            {
                continue;
            }

            // Create copy of board for new board
            Dictionary <int, PieceState> newBoard = new Dictionary <int, PieceState>();
            foreach (KeyValuePair <int, PieceState> b in board)
            {
                newBoard.Add(b.Key, b.Value);
            }
            // Attempt a move and evaluate it
            if (MakeMove(newBoard, id, turn, false) == 0)
            {
                continue;
            }
            newBoard[id] = (turn == 0) ? PieceState.BLACK : PieceState.WHITE;
            ScoreMovePair current = minimax(newBoard, (turn == 0) ? 1 : 0, maxDepth, currDepth + 1, best.Score, moveCount + 1);
            if (turn == 0) // Maximize
            {
                if (current.Score > prune)
                {
                    return(current);
                }
                if (current.Score > best.Score)
                {
                    best.Score = current.Score;
                    best.Move  = id;
                }
            }
            else // Minimize
            {
                if (current.Score < prune)
                {
                    return(current);
                }
                if (current.Score < best.Score)
                {
                    best.Score = current.Score;
                    best.Move  = id;
                }
            }
        }
        return(best);
    }
コード例 #2
0
ファイル: Minimax.cs プロジェクト: cococo111111/Reversi
    private ScoreMovePair minimax(Dictionary <int, PieceState> board, int turn, int maxDepth, int currDepth, int prune)
    {
        if (isGameOver(board) || currDepth == maxDepth)
        {
            if (GameOptions.Instance.SMART)
            {
                return(new ScoreMovePair(-1, weightedEvaluation(board, (turn == 0) ? 1 : 0)));
            }
            else
            {
                return(new ScoreMovePair(-1, unweightedEvaluation(board, (turn == 0) ? 1 : 0)));
            }
        }
        ScoreMovePair best = new ScoreMovePair(-1, 0); // Initialize best move to none

        if (turn == 0)                                 // Turn is AI's
        {
            best.Score = int.MinValue;
        }
        else // Turn is player's
        {
            best.Score = int.MaxValue;
        }
        for (int i = 0; i < 64; i++) // Iterate through board positions
        {
            // If move not available skip
            if (board[i] != PieceState.NONE)
            {
                continue;
            }

            // Create copy of board for new board
            Dictionary <int, PieceState> newBoard = new Dictionary <int, PieceState>();
            foreach (KeyValuePair <int, PieceState> b in board)
            {
                newBoard.Add(b.Key, b.Value);
            }
            // Attempt a move and evaluate it
            if (MakeMove(newBoard, i, turn, false) == 0)
            {
                continue;
            }
            newBoard[i] = (turn == 0) ? PieceState.BLACK : PieceState.WHITE;
            ScoreMovePair current = minimax(newBoard, (turn == 0) ? 1 : 0, maxDepth, currDepth + 1, best.Score);
            if (turn == 0) // Maximize
            {
                if (current.Score > prune)
                {
                    return(current);
                }
                if (current.Score > best.Score)
                {
                    best.Score = current.Score;
                    best.Move  = i;
                }
            }
            else // Minimize
            {
                if (current.Score < prune)
                {
                    return(current);
                }
                if (current.Score < best.Score)
                {
                    best.Score = current.Score;
                    best.Move  = i;
                }
            }
        }

        return(best);
    }