Пример #1
0
        public static int negamaxWithAlphaBeta(int alpha, int beta, int quieseDepth, int depth, ulong WP, ulong WN, ulong WB, ulong WR, ulong WQ, ulong WK, ulong BP, ulong BN, ulong BB, ulong BR, ulong BQ, ulong BK, ulong EP, bool CWK, bool CWQ, bool CBK, bool CBQ, bool white)
        {
            ulong hashCode = Zobrist.getZobristHash(WP, WN, WB, WR, WQ, WK, BP, BN, BB, BR, BQ, BK, EP, CWK, CWQ, CBK, CBQ, white);

            if (transpositionTable.ContainsKey(hashCode) && transpositionTable[hashCode].depth >= depth)
            {
                NodeData data = transpositionTable[hashCode];
                if (data.type == NodeData.Type.Exact)
                {
                    return(data.value);
                }
                if (data.type == NodeData.Type.Alpha)
                {
                    alpha = Math.Max(data.value, alpha);
                }
                else if (data.type == NodeData.Type.Beta)
                {
                    beta = Math.Min(beta, data.value);
                }
                if (alpha >= beta)
                {
                    return(data.value);
                }
            }

            if (depth == 0)
            {
                int value = Evalue.evalue(WP, WN, WB, WR, WQ, WK, BP, BN, BB, BR, BQ, BK, white);
                return(value);
            }
            string legalMove = Moves.LegalMoves(WP, WN, WB, WR, WQ, WK, BP, BN, BB, BR, BQ, BK, EP, CWK, CWQ, CBK, CBQ, white);

            if (legalMove.Length == 0)
            {
                if ((white && (WK & Moves.unSafeForWhite(WP, WN, WB, WR, WQ, WK, BP, BN, BB, BR, BQ, BK)) == 0) ||
                    (!white && (BK & Moves.unSafeForBlack(WP, WN, WB, WR, WQ, WK, BP, BN, BB, BR, BQ, BK)) == 0))
                {
                    return(0);
                }
                else
                {
                    return(-20000);
                }
            }
            int bestValue = -20000;
            int moveCount = legalMove.Length / 4;

            string[] moves = new string[moveCount];
            for (int i = 0; i < moveCount; i++)
            {
                moves[i] = legalMove.Substring(i * 4, 4);
            }
            for (int i = 0; i < moveCount; i++)
            {
                ulong WRt = Moves.makeMoveCastle(WR, WK | BK, moves[i], 'R');
                ulong BRt = Moves.makeMoveCastle(BR, WK | BK, moves[i], 'r');
                WRt = Moves.makeMove(WR, moves[i], 'R');
                BRt = Moves.makeMove(BR, moves[i], 'r');
                ulong WPt = Moves.makeMove(WP, moves[i], 'P'), WNt = Moves.makeMove(WN, moves[i], 'N'),
                      WBt = Moves.makeMove(WB, moves[i], 'B'),
                      WQt = Moves.makeMove(WQ, moves[i], 'Q'), WKt = Moves.makeMove(WK, moves[i], 'K'),
                      BPt = Moves.makeMove(BP, moves[i], 'p'), BNt = Moves.makeMove(BN, moves[i], 'n'),
                      BBt = Moves.makeMove(BB, moves[i], 'b'),
                      BQt = Moves.makeMove(BQ, moves[i], 'q'), BKt = Moves.makeMove(BK, moves[i], 'k'),
                      EPt = Moves.makeMoveEP(WP | BP, moves[i]);
                bool CWKt = CWK, CWQt = CWQ, CBKt = CBK, CBQt = CBQ;
                if (char.IsDigit(moves[i][3]))
                {
                    int start = (moves[i][0] - '0') * 8 + moves[i][1] - '0';
                    if (((1ul << start) & WK) != 0)
                    {
                        CWKt = false; CWQt = false;
                    }
                    else if (((1ul << start) & BK) != 0)
                    {
                        CBKt = false; CBQt = false;
                    }
                    else if (((1ul << start) & WR & (1ul << 63)) != 0)
                    {
                        CWKt = false;
                    }
                    else if (((1ul << start) & WR & (1ul << 56)) != 0)
                    {
                        CWQt = false;
                    }
                    else if (((1ul << start) & BR & (1ul << 7)) != 0)
                    {
                        CBKt = false;
                    }
                    else if (((1ul << start) & BR & 1ul) != 0)
                    {
                        CBQt = false;
                    }
                }
                int childValue = -negamaxWithAlphaBeta(-beta, -alpha, quieseDepth, depth - 1, WPt, WNt, WBt, WRt, WQt, WKt, BPt, BNt, BBt, BRt, BQt, BKt, EPt, CWKt, CWQt, CBKt, CBQt, white ? false : true);
                bestValue = Math.Max(bestValue, childValue);
                alpha     = Math.Max(alpha, childValue);
                if (alpha >= beta)
                {
                    break;
                }
            }
            hashCode = Zobrist.getZobristHash(WP, WN, WB, WR, WQ, WK, BP, BN, BB, BR, BQ, BK, EP, CWK, CWQ, CBK, CBQ, white);
            if (bestValue <= alpha)
            {
                transpositionTable.AddOrUpdate(hashCode, new NodeData(bestValue, depth, NodeData.Type.Beta, legalMove), (key, oldData) => oldData = new NodeData(bestValue, depth, NodeData.Type.Beta, legalMove));
            }
            else if (bestValue >= beta)
            {
                transpositionTable.AddOrUpdate(hashCode, new NodeData(bestValue, depth, NodeData.Type.Alpha, legalMove), (key, oldData) => oldData = new NodeData(bestValue, depth, NodeData.Type.Alpha, legalMove));
            }
            else
            {
                transpositionTable.AddOrUpdate(hashCode, new NodeData(bestValue, depth, NodeData.Type.Exact, ""), (key, oldData) => oldData = new NodeData(bestValue, depth, NodeData.Type.Exact, ""));
            }
            return(bestValue);
        }