Example #1
0
    int Min(ChessBoardSnapshot boardPosition, int depth)
    {
        if (depth <= 0 || boardPosition.IsEndGame())
        {
            return(GameManager.Instance.CalculateScore(boardPosition, playerType));
        }

        int lowestScore = int.MaxValue;

        ChessBoardSnapshot[] nextBoardPositions = FindPossibleMoves(boardPosition, playerType.ToOpposite());
        for (int i = 0; i < nextBoardPositions.Length; i++)
        {
            ChessBoardSnapshot board = nextBoardPositions[i];
            int score = Max(board, depth - 1);
            if (score < lowestScore)
            {
                lowestScore = score;
            }
        }
        return(lowestScore);
    }
Example #2
0
    int AlphaBeta(ChessBoardSnapshot boardPosition, int depth, int alpha, int beta, bool maximizingPlayer)
    {
        int         origAlpha = alpha;
        int         origBeta  = beta;
        MinimaxNode node      = new MinimaxNode();

        // Transposition Table Lookup; node is the lookup key for ttEntry
        ulong hash = boardPosition.board.ToZobristHash();

        if (tTable.ContainsKey(hash))
        {
            node = tTable[hash];

            if (node.depth >= depth)
            {
                switch (node.flag)
                {
                case MinimaxNodeFlag.Exact:
                    return(node.eval);

                case MinimaxNodeFlag.LowerBound:
                    if (node.eval > alpha)
                    {
                        alpha = node.eval;
                    }
                    break;

                case MinimaxNodeFlag.UpperBound:
                    if (node.eval < beta)
                    {
                        beta = node.eval;
                    }
                    break;
                }

                if (beta <= alpha)
                {
                    return(node.eval);
                }
            }
        }

        // Minimax + Alpha Beta Pruning
        if (depth <= 0 || boardPosition.IsEndGame())
        {
            return(GameManager.Instance.CalculateScore(boardPosition, playerType));
        }

        int val = 0;

        if (maximizingPlayer)
        {
            val = int.MinValue;
            ChessBoardSnapshot[] nextBoardPositions = FindPossibleMoves(boardPosition, playerType);

            for (int i = 0; i < nextBoardPositions.Length; i++)
            {
                int newValue = AlphaBeta(nextBoardPositions[i], depth - 1, alpha, beta, false);

                if (newValue > val)
                {
                    val = newValue;
                }
                if (val > alpha)
                {
                    alpha = val;
                }
                if (beta <= alpha)
                {
                    break;
                }
            }
        }
        else
        {
            val = int.MaxValue;
            ChessBoardSnapshot[] nextBoardPositions = FindPossibleMoves(boardPosition, playerType.ToOpposite());

            for (int i = 0; i < nextBoardPositions.Length; i++)
            {
                int newValue = AlphaBeta(nextBoardPositions[i], depth - 1, alpha, beta, true);

                if (newValue < val)
                {
                    val = newValue;
                }
                if (val < beta)
                {
                    beta = val;
                }
                if (beta <= alpha)
                {
                    break;
                }
            }
        }

        // Transposition Table Store; node is the lookup key for ttEntry
        node.hash = hash;
        node.eval = val;

        if (val <= origAlpha)
        {
            node.flag = MinimaxNodeFlag.UpperBound;
        }
        else if (val >= origBeta)
        {
            node.flag = MinimaxNodeFlag.LowerBound;
        }
        else
        {
            node.flag = MinimaxNodeFlag.Exact;
        }

        node.depth = depth;

        if (tTable.ContainsKey(hash))
        {
            tTable[hash] = node;
        }
        else
        {
            tTable.Add(hash, node);
        }

        return(val);
    }