Beispiel #1
0
        /** Implements special knowledge for some endgame situations. */
        private int endGameEval(Position pos, int oldScore)
        {
            int score = oldScore;
            if (pos.wMtrl + pos.bMtrl > 6 * rV)
            return score;
            int wMtrlPawns = pos.wMtrlPawns;
            int bMtrlPawns = pos.bMtrlPawns;
            int wMtrlNoPawns = pos.wMtrl - wMtrlPawns;
            int bMtrlNoPawns = pos.bMtrl - bMtrlPawns;

            bool handled = false;
            if ((wMtrlPawns + bMtrlPawns == 0) && (wMtrlNoPawns < rV) && (bMtrlNoPawns < rV)) {
            // King + minor piece vs king + minor piece is a draw
            return 0;
            }
            if (!handled && (pos.wMtrl == qV) && (pos.bMtrl == pV) &&
            (BITS.bitCount(pos.pieceTypeBB[Piece.WQUEEN]) == 1)) {
            int wk = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.WKING]);
            int wq = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.WQUEEN]);
            int bk = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.BKING]);
            int bp = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.BPAWN]);
            score = evalKQKP(wk, wq, bk, bp);
            handled = true;
            }
            if (!handled && (pos.bMtrl == qV) && (pos.wMtrl == pV) &&
            (BITS.bitCount(pos.pieceTypeBB[Piece.BQUEEN]) == 1)) {
            int bk = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.BKING]);
            int bq = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.BQUEEN]);
            int wk = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.WKING]);
            int wp = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.WPAWN]);
            score = -evalKQKP(63-bk, 63-bq, 63-wk, 63-wp);
            handled = true;
            }
            if (!handled && (score > 0)) {
            if ((wMtrlPawns == 0) && (wMtrlNoPawns <= bMtrlNoPawns + bV)) {
                if (wMtrlNoPawns < rV) {
                    return -pos.bMtrl / 50;
                } else {
                    score /= 8;         // Too little excess material, probably draw
                    handled = true;
                }
            } else if ((pos.pieceTypeBB[Piece.WROOK] | pos.pieceTypeBB[Piece.WKNIGHT] |
                        pos.pieceTypeBB[Piece.WQUEEN]) == 0) {
                // Check for rook pawn + wrong color bishop
                if (((pos.pieceTypeBB[Piece.WPAWN] & BitBoard.maskBToHFiles) == 0) &&
                    ((pos.pieceTypeBB[Piece.WBISHOP] & BitBoard.maskLightSq) == 0) &&
                    ((pos.pieceTypeBB[Piece.BKING] & 0x0303000000000000L) != 0)) {
                    return 0;
                } else
                if (((pos.pieceTypeBB[Piece.WPAWN] & BitBoard.maskAToGFiles) == 0) &&
                    ((pos.pieceTypeBB[Piece.WBISHOP] & BitBoard.maskDarkSq) == 0) &&
                    ((pos.pieceTypeBB[Piece.BKING] & 0xC0C0000000000000L) != 0)) {
                    return 0;
                }
            }
            }
            if (!handled) {
            if (bMtrlPawns == 0) {
                if (wMtrlNoPawns - bMtrlNoPawns > bV) {
                    int wKnights = BITS.bitCount(pos.pieceTypeBB[Piece.WKNIGHT]);
                    int wBishops = BITS.bitCount(pos.pieceTypeBB[Piece.WBISHOP]);
                    if ((wKnights == 2) && (wMtrlNoPawns == 2 * nV) && (bMtrlNoPawns == 0)) {
                        score /= 50;    // KNNK is a draw
                    } else if ((wKnights == 1) && (wBishops == 1) && (wMtrlNoPawns == nV + bV) && (bMtrlNoPawns == 0)) {
                        score /= 10;
                        score += nV + bV + 300;
                        int kSq = pos.getKingSq(false);
                        int x = Position.getX(kSq);
                        int y = Position.getY(kSq);
                        if ((pos.pieceTypeBB[Piece.WBISHOP] & BitBoard.maskDarkSq) != 0) {
                            score += (7 - distToH1A8[7-y][7-x]) * 10;
                        } else {
                            score += (7 - distToH1A8[7-y][x]) * 10;
                        }
                    } else {
                        score += 300;       // Enough excess material, should win
                    }
                    handled = true;
                } else if ((wMtrlNoPawns + bMtrlNoPawns == 0) && (wMtrlPawns == pV)) { // KPK
                    int wp = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.WPAWN]);
                    score = kpkEval(pos.getKingSq(true), pos.getKingSq(false),
                                    wp, pos.whiteMove);
                    handled = true;
                }
            }
            }
            if (!handled && (score < 0)) {
            if ((bMtrlPawns == 0) && (bMtrlNoPawns <= wMtrlNoPawns + bV)) {
                if (bMtrlNoPawns < rV) {
                    return pos.wMtrl / 50;
                } else {
                    score /= 8;         // Too little excess material, probably draw
                    handled = true;
                }
            } else if ((pos.pieceTypeBB[Piece.BROOK] | pos.pieceTypeBB[Piece.BKNIGHT] |
                        pos.pieceTypeBB[Piece.BQUEEN]) == 0) {
                // Check for rook pawn + wrong color bishop
                if (((pos.pieceTypeBB[Piece.BPAWN] & BitBoard.maskBToHFiles) == 0) &&
                    ((pos.pieceTypeBB[Piece.BBISHOP] & BitBoard.maskDarkSq) == 0) &&
                    ((pos.pieceTypeBB[Piece.WKING] & 0x0303L) != 0)) {
                    return 0;
                } else
                if (((pos.pieceTypeBB[Piece.BPAWN] & BitBoard.maskAToGFiles) == 0) &&
                    ((pos.pieceTypeBB[Piece.BBISHOP] & BitBoard.maskLightSq) == 0) &&
                    ((pos.pieceTypeBB[Piece.WKING] & 0xC0C0L) != 0)) {
                    return 0;
                }
            }
            }
            if (!handled) {
            if (wMtrlPawns == 0) {
                if (bMtrlNoPawns - wMtrlNoPawns > bV) {
                    int bKnights = BITS.bitCount(pos.pieceTypeBB[Piece.BKNIGHT]);
                    int bBishops = BITS.bitCount(pos.pieceTypeBB[Piece.BBISHOP]);
                    if ((bKnights == 2) && (bMtrlNoPawns == 2 * nV) && (wMtrlNoPawns == 0)) {
                        score /= 50;    // KNNK is a draw
                    } else if ((bKnights == 1) && (bBishops == 1) && (bMtrlNoPawns == nV + bV) && (wMtrlNoPawns == 0)) {
                        score /= 10;
                        score -= nV + bV + 300;
                        int kSq = pos.getKingSq(true);
                        int x = Position.getX(kSq);
                        int y = Position.getY(kSq);
                        if ((pos.pieceTypeBB[Piece.BBISHOP] & BitBoard.maskDarkSq) != 0) {
                            score -= (7 - distToH1A8[7-y][7-x]) * 10;
                        } else {
                            score -= (7 - distToH1A8[7-y][x]) * 10;
                        }
                    } else {
                        score -= 300;       // Enough excess material, should win
                    }
                    handled = true;
                } else if ((wMtrlNoPawns + bMtrlNoPawns == 0) && (bMtrlPawns == pV)) { // KPK
                    int bp = BitBoard.numberOfTrailingZeros(pos.pieceTypeBB[Piece.BPAWN]);
                    score = -kpkEval(63-pos.getKingSq(false), 63-pos.getKingSq(true),
                                     63-bp, !pos.whiteMove);
                    handled = true;
                }
            }
            }
            return score;

            // FIXME! Add evaluation of KRKP
            // FIXME! Add evaluation of KRPKR   : eg 8/8/8/5pk1/1r6/R7/8/4K3 w - - 0 74
            // FIXME! KRBKR is very hard to draw
        }
Beispiel #2
0
        private int pawnBonus(Position pos)
        {
            ulong key = pos.pawnZobristHash();
            PawnHashData phd = pawnHash[(int)key & (pawnHash.Length - 1)];
            if (phd.key != key)
            computePawnHashData(pos, phd);
            int score = phd.score;

            int hiMtrl = qV + rV;
            score += interpolate(pos.bMtrl - pos.bMtrlPawns, 0, 2 * phd.passedBonusW, hiMtrl, phd.passedBonusW);
            score -= interpolate(pos.wMtrl - pos.wMtrlPawns, 0, 2 * phd.passedBonusB, hiMtrl, phd.passedBonusB);

            // Passed pawns are more dangerous if enemy king is far away
            int mtrlNoPawns;
            int highMtrl = qV + rV;
            ulong m = phd.passedPawnsW;
            if (m != 0) {
            mtrlNoPawns = pos.bMtrl - pos.bMtrlPawns;
            if (mtrlNoPawns < highMtrl) {
                int kingPos = pos.getKingSq(false);
                int kingX = Position.getX(kingPos);
                int kingY = Position.getY(kingPos);
                while (m != 0) {
                    int sq = BitBoard.numberOfTrailingZeros(m);
                    int x = Position.getX(sq);
                    int y = Position.getY(sq);
                    int pawnDist = Math.Min(5, 7 - y);
                    int kingDistX = Math.Abs(kingX - x);
                    int kingDistY = Math.Abs(kingY - 7);
                    int kingDist = Math.Max(kingDistX, kingDistY);
                    int kScore = kingDist * 4;
                    if (kingDist > pawnDist) kScore += (kingDist - pawnDist) * (kingDist - pawnDist);
                    score += interpolate(mtrlNoPawns, 0, kScore, highMtrl, 0);
                    if (!pos.whiteMove)
                        kingDist--;
                    if ((pawnDist < kingDist) && (mtrlNoPawns == 0))
                        score += 500; // King can't stop pawn
                    m &= m-1;
                }
            }
            }
            m = phd.passedPawnsB;
            if (m != 0) {
            mtrlNoPawns = pos.wMtrl - pos.wMtrlPawns;
            if (mtrlNoPawns < highMtrl) {
                int kingPos = pos.getKingSq(true);
                int kingX = Position.getX(kingPos);
                int kingY = Position.getY(kingPos);
                while (m != 0) {
                    int sq = BitBoard.numberOfTrailingZeros(m);
                    int x = Position.getX(sq);
                    int y = Position.getY(sq);
                    int pawnDist = Math.Min(5, y);
                    int kingDistX = Math.Abs(kingX - x);
                    int kingDistY = Math.Abs(kingY - 0);
                    int kingDist = Math.Max(kingDistX, kingDistY);
                    int kScore = kingDist * 4;
                    if (kingDist > pawnDist) kScore += (kingDist - pawnDist) * (kingDist - pawnDist);
                    score -= interpolate(mtrlNoPawns, 0, kScore, highMtrl, 0);
                    if (pos.whiteMove)
                        kingDist--;
                    if ((pawnDist < kingDist) && (mtrlNoPawns == 0))
                        score -= 500; // King can't stop pawn
                    m &= m-1;
                }
            }
            }

            return score;
        }
Beispiel #3
0
        /**
         * Generate and return a list of pseudo-legal moves.
         * Pseudo-legal means that the moves doesn't necessarily defend from check threats.
         */
        public MoveList pseudoLegalMoves(Position pos)
        {
            MoveList moveList = getMoveListObj();
            ulong occupied = pos.whiteBB | pos.blackBB;
            if (pos.whiteMove) {
            int sq = 0;
            ulong m = 0;
            // Queen moves
            ulong squares = pos.pieceTypeBB[Piece.WQUEEN];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = (BitBoard.rookAttacks(sq, occupied) | BitBoard.bishopAttacks(sq, occupied)) & ~pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Rook moves
            squares = pos.pieceTypeBB[Piece.WROOK];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.rookAttacks(sq, occupied) & ~pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Bishop moves
            squares = pos.pieceTypeBB[Piece.WBISHOP];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.bishopAttacks(sq, occupied) & ~pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // King moves
            {
                sq = pos.getKingSq(true);
                m = BitBoard.kingAttacks[sq] & ~pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                int k0 = 4;
                if (sq == k0) {
                    ulong OO_SQ = 0x60L;
                    ulong OOO_SQ = 0xEL;
                    if (((pos.getCastleMask() & (1 << Position.H1_CASTLE)) != 0) &&
                        ((OO_SQ & (pos.whiteBB | pos.blackBB)) == 0) &&
                        (pos.getPiece(k0 + 3) == Piece.WROOK) &&
                        !sqAttacked(pos, k0) &&
                        !sqAttacked(pos, k0 + 1)) {
                        setMove(moveList, k0, k0 + 2, Piece.EMPTY);
                    }
                    if (((pos.getCastleMask() & (1 << Position.A1_CASTLE)) != 0) &&
                        ((OOO_SQ & (pos.whiteBB | pos.blackBB)) == 0) &&
                        (pos.getPiece(k0 - 4) == Piece.WROOK) &&
                        !sqAttacked(pos, k0) &&
                        !sqAttacked(pos, k0 - 1)) {
                        setMove(moveList, k0, k0 - 2, Piece.EMPTY);
                    }
                }
            }

            // Knight moves
            ulong knights = pos.pieceTypeBB[Piece.WKNIGHT];
            while (knights != 0) {
                sq = BitBoard.numberOfTrailingZeros(knights);
                m = BitBoard.knightAttacks[sq] & ~pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                knights &= knights-1;
            }

            // Pawn moves
            ulong pawns = pos.pieceTypeBB[Piece.WPAWN];
            m = (pawns << 8) & ~occupied;
            if (addPawnMovesByMask(moveList, pos, m, -8, true)) return moveList;
            m = ((m & BitBoard.maskRow3) << 8) & ~occupied;
            addPawnDoubleMovesByMask(moveList, pos, m, -16);

            int epSquare = pos.getEpSquare();
            ulong epMask = (epSquare >= 0) ? (1UL << epSquare) : 0L;
            m = (pawns << 7) & BitBoard.maskAToGFiles & (pos.blackBB | epMask);
            if (addPawnMovesByMask(moveList, pos, m, -7, true)) return moveList;

            m = (pawns << 9) & BitBoard.maskBToHFiles & (pos.blackBB | epMask);
            if (addPawnMovesByMask(moveList, pos, m, -9, true)) return moveList;
            } else {
            int sq = 0;
            ulong m = 0;
            // Queen moves
            ulong squares = pos.pieceTypeBB[Piece.BQUEEN];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = (BitBoard.rookAttacks(sq, occupied) | BitBoard.bishopAttacks(sq, occupied)) & ~pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Rook moves
            squares = pos.pieceTypeBB[Piece.BROOK];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.rookAttacks(sq, occupied) & ~pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Bishop moves
            squares = pos.pieceTypeBB[Piece.BBISHOP];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.bishopAttacks(sq, occupied) & ~pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // King moves
            {
                sq = pos.getKingSq(false);
                m = BitBoard.kingAttacks[sq] & ~pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                int k0 = 60;
                if (sq == k0) {
                    ulong OO_SQ = 0x6000000000000000L;
                    ulong OOO_SQ = 0xE00000000000000L;
                    if (((pos.getCastleMask() & (1 << Position.H8_CASTLE)) != 0) &&
                        ((OO_SQ & (pos.whiteBB | pos.blackBB)) == 0) &&
                        (pos.getPiece(k0 + 3) == Piece.BROOK) &&
                        !sqAttacked(pos, k0) &&
                        !sqAttacked(pos, k0 + 1)) {
                        setMove(moveList, k0, k0 + 2, Piece.EMPTY);
                    }
                    if (((pos.getCastleMask() & (1 << Position.A8_CASTLE)) != 0) &&
                        ((OOO_SQ & (pos.whiteBB | pos.blackBB)) == 0) &&
                        (pos.getPiece(k0 - 4) == Piece.BROOK) &&
                        !sqAttacked(pos, k0) &&
                        !sqAttacked(pos, k0 - 1)) {
                        setMove(moveList, k0, k0 - 2, Piece.EMPTY);
                    }
                }
            }

            // Knight moves
            ulong knights = pos.pieceTypeBB[Piece.BKNIGHT];
            while (knights != 0) {
                sq = BitBoard.numberOfTrailingZeros(knights);
                m = BitBoard.knightAttacks[sq] & ~pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                knights &= knights-1;
            }

            // Pawn moves
            ulong pawns = pos.pieceTypeBB[Piece.BPAWN];
            m = (pawns >> 8) & ~occupied;
            if (addPawnMovesByMask(moveList, pos, m, 8, true)) return moveList;
            m = ((m & BitBoard.maskRow6) >> 8) & ~occupied;
            addPawnDoubleMovesByMask(moveList, pos, m, 16);

            int epSquare = pos.getEpSquare();
            ulong epMask = (epSquare >= 0) ? (1UL << epSquare) : 0L;
            m = (pawns >> 9) & BitBoard.maskAToGFiles & (pos.whiteBB | epMask);
            if (addPawnMovesByMask(moveList, pos, m, 9, true)) return moveList;

            m = (pawns >> 7) & BitBoard.maskBToHFiles & (pos.whiteBB | epMask);
            if (addPawnMovesByMask(moveList, pos, m, 7, true)) return moveList;
            }
            return moveList;
        }
Beispiel #4
0
        /**
         * Static evaluation of a position.
         * @param pos The position to evaluate.
         * @return The evaluation score, measured in centipawns.
         *         Positive values are good for the side to make the next move.
         */
        public int evalPos(Position pos)
        {
            int score = pos.wMtrl - pos.bMtrl;

            wKingAttacks = bKingAttacks = 0;
            wKingZone = BitBoard.kingAttacks[pos.getKingSq(true)]; wKingZone |= wKingZone << 8;
            bKingZone = BitBoard.kingAttacks[pos.getKingSq(false)]; bKingZone |= bKingZone >> 8;
            wAttacksBB = bAttacksBB = 0L;

            score += pieceSquareEval(pos);
            score += pawnBonus(pos);
            score += tradeBonus(pos);
            score += castleBonus(pos);

            score += rookBonus(pos);
            score += bishopEval(pos, score);
            score += threatBonus(pos);
            score += kingSafety(pos);
            score = endGameEval(pos, score);

            if (!pos.whiteMove)
            score = -score;
            return score;

            // FIXME! Test penalty if side to move has >1 hanging piece

            // FIXME! Test "tempo value"
        }
Beispiel #5
0
        /** Generate captures, checks, and possibly some other moves that are too hard to filter out. */
        public MoveList pseudoLegalCapturesAndChecks(Position pos)
        {
            MoveList moveList = getMoveListObj();
            ulong occupied = pos.whiteBB | pos.blackBB;
            if (pos.whiteMove) {
            int sq = 0;
            ulong m = 0;
            int bKingSq = pos.getKingSq(false);
            ulong discovered = 0; // Squares that could generate discovered checks
            ulong kRookAtk = BitBoard.rookAttacks(bKingSq, occupied);
            if ((BitBoard.rookAttacks(bKingSq, occupied & ~kRookAtk) &
                    (pos.pieceTypeBB[Piece.WQUEEN] | pos.pieceTypeBB[Piece.WROOK])) != 0)
                discovered |= kRookAtk;
            ulong kBishAtk = BitBoard.bishopAttacks(bKingSq, occupied);
            if ((BitBoard.bishopAttacks(bKingSq, occupied & ~kBishAtk) &
                    (pos.pieceTypeBB[Piece.WQUEEN] | pos.pieceTypeBB[Piece.WBISHOP])) != 0)
                discovered |= kBishAtk;

            // Queen moves
            ulong squares = pos.pieceTypeBB[Piece.WQUEEN];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = (BitBoard.rookAttacks(sq, occupied) | BitBoard.bishopAttacks(sq, occupied));
                if ((discovered & (1UL<<sq)) == 0) m &= (pos.blackBB | kRookAtk | kBishAtk);
                m &= ~pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Rook moves
            squares = pos.pieceTypeBB[Piece.WROOK];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.rookAttacks(sq, occupied);
                if ((discovered & (1UL<<sq)) == 0) m &= (pos.blackBB | kRookAtk);
                m &= ~pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Bishop moves
            squares = pos.pieceTypeBB[Piece.WBISHOP];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.bishopAttacks(sq, occupied);
                if ((discovered & (1UL<<sq)) == 0) m &= (pos.blackBB | kBishAtk);
                m &= ~pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // King moves
            {
                sq = pos.getKingSq(true);
                m = BitBoard.kingAttacks[sq];
                m &= ((discovered & (1UL<<sq)) == 0) ? pos.blackBB : ~pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                int k0 = 4;
                if (sq == k0) {
                    ulong OO_SQ = 0x60L;
                    ulong OOO_SQ = 0xEL;
                    if (((pos.getCastleMask() & (1 << Position.H1_CASTLE)) != 0) &&
                        ((OO_SQ & (pos.whiteBB | pos.blackBB)) == 0) &&
                        (pos.getPiece(k0 + 3) == Piece.WROOK) &&
                        !sqAttacked(pos, k0) &&
                        !sqAttacked(pos, k0 + 1)) {
                        setMove(moveList, k0, k0 + 2, Piece.EMPTY);
                    }
                    if (((pos.getCastleMask() & (1 << Position.A1_CASTLE)) != 0) &&
                        ((OOO_SQ & (pos.whiteBB | pos.blackBB)) == 0) &&
                        (pos.getPiece(k0 - 4) == Piece.WROOK) &&
                        !sqAttacked(pos, k0) &&
                        !sqAttacked(pos, k0 - 1)) {
                        setMove(moveList, k0, k0 - 2, Piece.EMPTY);
                    }
                }
            }

            // Knight moves
            ulong knights = pos.pieceTypeBB[Piece.WKNIGHT];
            ulong kKnightAtk = BitBoard.knightAttacks[bKingSq];
            while (knights != 0) {
                sq = BitBoard.numberOfTrailingZeros(knights);
                m = BitBoard.knightAttacks[sq] & ~pos.whiteBB;
                if ((discovered & (1UL<<sq)) == 0) m &= (pos.blackBB | kKnightAtk);
                m &= ~pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                knights &= knights-1;
            }

            // Pawn moves
            // Captures
            ulong pawns = pos.pieceTypeBB[Piece.WPAWN];
            int epSquare = pos.getEpSquare();
            ulong epMask = (epSquare >= 0) ? (1UL << epSquare) : 0L;
            m = (pawns << 7) & BitBoard.maskAToGFiles & (pos.blackBB | epMask);
            if (addPawnMovesByMask(moveList, pos, m, -7, false)) return moveList;
            m = (pawns << 9) & BitBoard.maskBToHFiles & (pos.blackBB | epMask);
            if (addPawnMovesByMask(moveList, pos, m, -9, false)) return moveList;

            // Discovered checks and promotions
            ulong pawnAll = discovered | BitBoard.maskRow7;
            m = ((pawns & pawnAll) << 8) & ~(pos.whiteBB | pos.blackBB);
            if (addPawnMovesByMask(moveList, pos, m, -8, false)) return moveList;
            m = ((m & BitBoard.maskRow3) << 8) & ~(pos.whiteBB | pos.blackBB);
            addPawnDoubleMovesByMask(moveList, pos, m, -16);

            // Normal checks
            m = ((pawns & ~pawnAll) << 8) & ~(pos.whiteBB | pos.blackBB);
            if (addPawnMovesByMask(moveList, pos, m & BitBoard.bPawnAttacks[bKingSq], -8, false)) return moveList;
            m = ((m & BitBoard.maskRow3) << 8) & ~(pos.whiteBB | pos.blackBB);
            addPawnDoubleMovesByMask(moveList, pos, m & BitBoard.bPawnAttacks[bKingSq], -16);
            } else {
            int sq = 0;
            ulong m = 0;
            int wKingSq = pos.getKingSq(true);
            ulong discovered = 0; // Squares that could generate discovered checks
            ulong kRookAtk = BitBoard.rookAttacks(wKingSq, occupied);
            if ((BitBoard.rookAttacks(wKingSq, occupied & ~kRookAtk) &
                    (pos.pieceTypeBB[Piece.BQUEEN] | pos.pieceTypeBB[Piece.BROOK])) != 0)
                discovered |= kRookAtk;
            ulong kBishAtk = BitBoard.bishopAttacks(wKingSq, occupied);
            if ((BitBoard.bishopAttacks(wKingSq, occupied & ~kBishAtk) &
                    (pos.pieceTypeBB[Piece.BQUEEN] | pos.pieceTypeBB[Piece.BBISHOP])) != 0)
                discovered |= kBishAtk;

            // Queen moves
            ulong squares = pos.pieceTypeBB[Piece.BQUEEN];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = (BitBoard.rookAttacks(sq, occupied) | BitBoard.bishopAttacks(sq, occupied));
                if ((discovered & (1UL<<sq)) == 0) m &= pos.whiteBB | kRookAtk | kBishAtk;
                m &= ~pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Rook moves
            squares = pos.pieceTypeBB[Piece.BROOK];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.rookAttacks(sq, occupied);
                if ((discovered & (1UL<<sq)) == 0) m &= pos.whiteBB | kRookAtk;
                m &= ~pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Bishop moves
            squares = pos.pieceTypeBB[Piece.BBISHOP];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.bishopAttacks(sq, occupied);
                if ((discovered & (1UL<<sq)) == 0) m &= pos.whiteBB | kBishAtk;
                m &= ~pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // King moves
            {
                sq = pos.getKingSq(false);
                m = BitBoard.kingAttacks[sq];
                m &= ((discovered & (1UL<<sq)) == 0) ? pos.whiteBB : ~pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                int k0 = 60;
                if (sq == k0) {
                    ulong OO_SQ = 0x6000000000000000L;
                    ulong OOO_SQ = 0xE00000000000000L;
                    if (((pos.getCastleMask() & (1 << Position.H8_CASTLE)) != 0) &&
                        ((OO_SQ & (pos.whiteBB | pos.blackBB)) == 0) &&
                        (pos.getPiece(k0 + 3) == Piece.BROOK) &&
                        !sqAttacked(pos, k0) &&
                        !sqAttacked(pos, k0 + 1)) {
                        setMove(moveList, k0, k0 + 2, Piece.EMPTY);
                    }
                    if (((pos.getCastleMask() & (1 << Position.A8_CASTLE)) != 0) &&
                        ((OOO_SQ & (pos.whiteBB | pos.blackBB)) == 0) &&
                        (pos.getPiece(k0 - 4) == Piece.BROOK) &&
                        !sqAttacked(pos, k0) &&
                        !sqAttacked(pos, k0 - 1)) {
                        setMove(moveList, k0, k0 - 2, Piece.EMPTY);
                    }
                }
            }

            // Knight moves
            ulong knights = pos.pieceTypeBB[Piece.BKNIGHT];
            ulong kKnightAtk = BitBoard.knightAttacks[wKingSq];
            while (knights != 0) {
                sq = BitBoard.numberOfTrailingZeros(knights);
                m = BitBoard.knightAttacks[sq] & ~pos.blackBB;
                if ((discovered & (1UL<<sq)) == 0) m &= pos.whiteBB | kKnightAtk;
                m &= ~pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                knights &= knights-1;
            }

            // Pawn moves
            // Captures
            ulong pawns = pos.pieceTypeBB[Piece.BPAWN];
            int epSquare = pos.getEpSquare();
            ulong epMask = (epSquare >= 0) ? (1UL << epSquare) : 0L;
            m = (pawns >> 9) & BitBoard.maskAToGFiles & (pos.whiteBB | epMask);
            if (addPawnMovesByMask(moveList, pos, m, 9, false)) return moveList;
            m = (pawns >> 7) & BitBoard.maskBToHFiles & (pos.whiteBB | epMask);
            if (addPawnMovesByMask(moveList, pos, m, 7, false)) return moveList;

            // Discovered checks and promotions
            ulong pawnAll = discovered | BitBoard.maskRow2;
            m = ((pawns & pawnAll) >> 8) & ~(pos.whiteBB | pos.blackBB);
            if (addPawnMovesByMask(moveList, pos, m, 8, false)) return moveList;
            m = ((m & BitBoard.maskRow6) >> 8) & ~(pos.whiteBB | pos.blackBB);
            addPawnDoubleMovesByMask(moveList, pos, m, 16);

            // Normal checks
            m = ((pawns & ~pawnAll) >> 8) & ~(pos.whiteBB | pos.blackBB);
            if (addPawnMovesByMask(moveList, pos, m & BitBoard.wPawnAttacks[wKingSq], 8, false)) return moveList;
            m = ((m & BitBoard.maskRow6) >> 8) & ~(pos.whiteBB | pos.blackBB);
            addPawnDoubleMovesByMask(moveList, pos, m & BitBoard.wPawnAttacks[wKingSq], 16);
            }

            return moveList;
        }
Beispiel #6
0
 /**
  * Return true if making a move delivers check to the opponent
  */
 public static bool givesCheck(Position pos, Move m)
 {
     bool wtm = pos.whiteMove;
     int oKingSq = pos.getKingSq(!wtm);
     int oKing = wtm ? Piece.BKING : Piece.WKING;
     int p = Piece.makeWhite(m.promoteTo == Piece.EMPTY ? pos.getPiece(m.from) : m.promoteTo);
     int d1 = BitBoard.getDirection(m.to, oKingSq);
     switch (d1) {
     case 8: case -8: case 1: case -1: // Rook direction
     if ((p == Piece.WQUEEN) || (p == Piece.WROOK))
         if ((d1 != 0) && (/*MoveGen.*/ nextPiece(pos, m.to, d1) == oKing))
             return true;
     break;
     case 9: case 7: case -9: case -7: // Bishop direction
     if ((p == Piece.WQUEEN) || (p == Piece.WBISHOP)) {
         if ((d1 != 0) && (/*MoveGen.*/ nextPiece(pos, m.to, d1) == oKing))
             return true;
     } else if (p == Piece.WPAWN) {
         if (((d1 > 0) == wtm) && (pos.getPiece(m.to + d1) == oKing))
             return true;
     }
     break;
     default:
     if (d1 != 0) { // Knight direction
         if (p == Piece.WKNIGHT)
             return true;
     }
     break;
     }
     int d2 = BitBoard.getDirection(m.from, oKingSq);
     if ((d2 != 0) && (d2 != d1) && (/*MoveGen.*/ nextPiece(pos, m.from, d2) == oKing)) {
     int p2 = /*MoveGen.*/ nextPieceSafe(pos, m.from, -d2);
     switch (d2) {
     case 8: case -8: case 1: case -1: // Rook direction
         if ((p2 == (wtm ? Piece.WQUEEN : Piece.BQUEEN)) ||
             (p2 == (wtm ? Piece.WROOK : Piece.BROOK)))
             return true;
         break;
     case 9: case 7: case -9: case -7: // Bishop direction
         if ((p2 == (wtm ? Piece.WQUEEN : Piece.BQUEEN)) ||
             (p2 == (wtm ? Piece.WBISHOP : Piece.BBISHOP)))
             return true;
         break;
     }
     }
     if ((m.promoteTo != Piece.EMPTY) && (d1 != 0) && (d1 == d2)) {
     switch (d1) {
     case 8: case -8: case 1: case -1: // Rook direction
         if ((p == Piece.WQUEEN) || (p == Piece.WROOK))
             if ((d1 != 0) && (/*MoveGen.*/ nextPiece(pos, m.from, d1) == oKing))
                 return true;
         break;
     case 9: case 7: case -9: case -7: // Bishop direction
         if ((p == Piece.WQUEEN) || (p == Piece.WBISHOP)) {
             if ((d1 != 0) && (/*MoveGen.*/ nextPiece(pos, m.from, d1) == oKing))
                 return true;
         }
         break;
     }
     }
     if (p == Piece.WKING) {
     if (m.to - m.from == 2) { // O-O
         if (/*MoveGen.*/ nextPieceSafe(pos, m.from, -1) == oKing)
             return true;
         if (/*MoveGen.*/ nextPieceSafe(pos, m.from + 1, wtm ? 8 : -8) == oKing)
             return true;
     } else if (m.to - m.from == -2) { // O-O-O
         if (/*MoveGen.*/ nextPieceSafe(pos, m.from, 1) == oKing)
             return true;
         if (/*MoveGen.*/ nextPieceSafe(pos, m.from - 1, wtm ? 8 : -8) == oKing)
             return true;
     }
     } else if (p == Piece.WPAWN) {
     if (pos.getPiece(m.to) == Piece.EMPTY) {
         int dx = Position.getX(m.to) - Position.getX(m.from);
         if (dx != 0) { // en passant
             int epSq = m.from + dx;
             int d3 = BitBoard.getDirection(epSq, oKingSq);
             switch (d3) {
             case 9: case 7: case -9: case -7:
                 if (/*MoveGen.*/ nextPiece(pos, epSq, d3) == oKing) {
                     int p2 = /*MoveGen.*/ nextPieceSafe(pos, epSq, -d3);
                     if ((p2 == (wtm ? Piece.WQUEEN : Piece.BQUEEN)) ||
                         (p2 == (wtm ? Piece.WBISHOP : Piece.BBISHOP)))
                         return true;
                 }
                 break;
             case 1:
                 if (/*MoveGen.*/ nextPiece(pos, Math.Max(epSq, m.from), d3) == oKing) {
                     int p2 = /*MoveGen.*/ nextPieceSafe(pos, Math.Min(epSq, m.from), -d3);
                     if ((p2 == (wtm ? Piece.WQUEEN : Piece.BQUEEN)) ||
                         (p2 == (wtm ? Piece.WROOK : Piece.BROOK)))
                         return true;
                 }
                 break;
             case -1:
                 if (/*MoveGen.*/ nextPiece(pos, Math.Min(epSq, m.from), d3) == oKing) {
                     int p2 = /*MoveGen.*/ nextPieceSafe(pos, Math.Max(epSq, m.from), -d3);
                     if ((p2 == (wtm ? Piece.WQUEEN : Piece.BQUEEN)) ||
                         (p2 == (wtm ? Piece.WROOK : Piece.BROOK)))
                         return true;
                 }
                 break;
             }
         }
     }
     }
     return false;
 }
Beispiel #7
0
        public MoveList pseudoLegalCaptures(Position pos)
        {
            MoveList moveList = getMoveListObj();
            ulong occupied = pos.whiteBB | pos.blackBB;

            if (pos.whiteMove) {

            int sq = 0;
            ulong m = 0;

            // Queen moves
            ulong squares = pos.pieceTypeBB[Piece.WQUEEN];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = (BitBoard.rookAttacks(sq, occupied) | BitBoard.bishopAttacks(sq, occupied)) & pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Rook moves
            squares = pos.pieceTypeBB[Piece.WROOK];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.rookAttacks(sq, occupied) & pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Bishop moves
            squares = pos.pieceTypeBB[Piece.WBISHOP];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.bishopAttacks(sq, occupied) & pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Knight moves
            ulong knights = pos.pieceTypeBB[Piece.WKNIGHT];
            while (knights != 0) {
                sq = BitBoard.numberOfTrailingZeros(knights);
                m = BitBoard.knightAttacks[sq] & pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                knights &= knights-1;
            }

            // King moves
            sq = pos.getKingSq(true);
            m = BitBoard.kingAttacks[sq] & pos.blackBB;
            if (addMovesByMask(moveList, pos, sq, m)) return moveList;

            // Pawn moves
            ulong pawns = pos.pieceTypeBB[Piece.WPAWN];
            m = (pawns << 8) & ~(pos.whiteBB | pos.blackBB);
            m &= BitBoard.maskRow8;
            if (addPawnMovesByMask(moveList, pos, m, -8, false)) return moveList;

            int epSquare = pos.getEpSquare();
            ulong epMask = (epSquare >= 0) ? (1UL << epSquare) : 0L;
            m = (pawns << 7) & BitBoard.maskAToGFiles & (pos.blackBB | epMask);
            if (addPawnMovesByMask(moveList, pos, m, -7, false)) return moveList;
            m = (pawns << 9) & BitBoard.maskBToHFiles & (pos.blackBB | epMask);
            if (addPawnMovesByMask(moveList, pos, m, -9, false)) return moveList;
            } else {

            int sq = 0;
            ulong m = 0;

            // Queen moves
            ulong squares = pos.pieceTypeBB[Piece.BQUEEN];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = (BitBoard.rookAttacks(sq, occupied) | BitBoard.bishopAttacks(sq, occupied)) & pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Rook moves
            squares = pos.pieceTypeBB[Piece.BROOK];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.rookAttacks(sq, occupied) & pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Bishop moves
            squares = pos.pieceTypeBB[Piece.BBISHOP];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.bishopAttacks(sq, occupied) & pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Knight moves
            ulong knights = pos.pieceTypeBB[Piece.BKNIGHT];
            while (knights != 0) {
                sq = BitBoard.numberOfTrailingZeros(knights);
                m = BitBoard.knightAttacks[sq] & pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                knights &= knights-1;
            }

            // King moves
            sq = pos.getKingSq(false);
            m = BitBoard.kingAttacks[sq] & pos.whiteBB;
            if (addMovesByMask(moveList, pos, sq, m)) return moveList;

            // Pawn moves
            ulong pawns = pos.pieceTypeBB[Piece.BPAWN];
            m = (pawns >> 8) & ~(pos.whiteBB | pos.blackBB);
            m &= BitBoard.maskRow1;
            if (addPawnMovesByMask(moveList, pos, m, 8, false)) return moveList;

            int epSquare = pos.getEpSquare();
            ulong epMask = (epSquare >= 0) ? (1UL << epSquare) : 0L;
            m = (pawns >> 9) & BitBoard.maskAToGFiles & (pos.whiteBB | epMask);
            if (addPawnMovesByMask(moveList, pos, m, 9, false)) return moveList;
            m = (pawns >> 7) & BitBoard.maskBToHFiles & (pos.whiteBB | epMask);
            if (addPawnMovesByMask(moveList, pos, m, 7, false)) return moveList;
            }
            return moveList;
        }
Beispiel #8
0
        /**
         * Generate and return a list of pseudo-legal check evasion moves.
         * Pseudo-legal means that the moves doesn't necessarily defend from check threats.
         */
        public MoveList checkEvasions(Position pos)
        {
            MoveList moveList = getMoveListObj();
            ulong occupied = pos.whiteBB | pos.blackBB;
            if (pos.whiteMove) {
            int sq = 0;
            ulong m = 0;
            ulong kingThreats = pos.pieceTypeBB[Piece.BKNIGHT] & BitBoard.knightAttacks[pos.wKingSq];
            ulong rookPieces = pos.pieceTypeBB[Piece.BROOK] | pos.pieceTypeBB[Piece.BQUEEN];
            if (rookPieces != 0)
                kingThreats |= rookPieces & BitBoard.rookAttacks(pos.wKingSq, occupied);
            ulong bishPieces = pos.pieceTypeBB[Piece.BBISHOP] | pos.pieceTypeBB[Piece.BQUEEN];
            if (bishPieces != 0)
                kingThreats |= bishPieces & BitBoard.bishopAttacks(pos.wKingSq, occupied);
            kingThreats |= pos.pieceTypeBB[Piece.BPAWN] & BitBoard.wPawnAttacks[pos.wKingSq];
            ulong validTargets = 0;
            if ((kingThreats != 0) && ((kingThreats & (kingThreats-1)) == 0)) { // Exactly one attacking piece
                int threatSq = BitBoard.numberOfTrailingZeros(kingThreats);
                validTargets = kingThreats | BitBoard.squaresBetween[pos.wKingSq][threatSq];
            }
            validTargets |= pos.pieceTypeBB[Piece.BKING];
            // Queen moves
            ulong squares = pos.pieceTypeBB[Piece.WQUEEN];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = (BitBoard.rookAttacks(sq, occupied) | BitBoard.bishopAttacks(sq, occupied)) &
                            ~pos.whiteBB & validTargets;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Rook moves
            squares = pos.pieceTypeBB[Piece.WROOK];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.rookAttacks(sq, occupied) & ~pos.whiteBB & validTargets;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Bishop moves
            squares = pos.pieceTypeBB[Piece.WBISHOP];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.bishopAttacks(sq, occupied) & ~pos.whiteBB & validTargets;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // King moves
            {
                sq = pos.getKingSq(true);
                m = BitBoard.kingAttacks[sq] & ~pos.whiteBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
            }

            // Knight moves
            ulong knights = pos.pieceTypeBB[Piece.WKNIGHT];
            while (knights != 0) {
                sq = BitBoard.numberOfTrailingZeros(knights);
                m = BitBoard.knightAttacks[sq] & ~pos.whiteBB & validTargets;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                knights &= knights-1;
            }

            // Pawn moves
            ulong pawns = pos.pieceTypeBB[Piece.WPAWN];
            m = (pawns << 8) & ~occupied;
            if (addPawnMovesByMask(moveList, pos, m & validTargets, -8, true)) return moveList;
            m = ((m & BitBoard.maskRow3) << 8) & ~occupied;
            addPawnDoubleMovesByMask(moveList, pos, m & validTargets, -16);

            int epSquare = pos.getEpSquare();
            ulong epMask = (epSquare >= 0) ? (1UL << epSquare) : 0L;
            m = (pawns << 7) & BitBoard.maskAToGFiles & ((pos.blackBB & validTargets) | epMask);
            if (addPawnMovesByMask(moveList, pos, m, -7, true)) return moveList;

            m = (pawns << 9) & BitBoard.maskBToHFiles & ((pos.blackBB & validTargets) | epMask);
            if (addPawnMovesByMask(moveList, pos, m, -9, true)) return moveList;
            } else {
            int sq = 0;
            ulong m = 0;
            ulong kingThreats = pos.pieceTypeBB[Piece.WKNIGHT] & BitBoard.knightAttacks[pos.bKingSq];
            ulong rookPieces = pos.pieceTypeBB[Piece.WROOK] | pos.pieceTypeBB[Piece.WQUEEN];
            if (rookPieces != 0)
                kingThreats |= rookPieces & BitBoard.rookAttacks(pos.bKingSq, occupied);
            ulong bishPieces = pos.pieceTypeBB[Piece.WBISHOP] | pos.pieceTypeBB[Piece.WQUEEN];
            if (bishPieces != 0)
                kingThreats |= bishPieces & BitBoard.bishopAttacks(pos.bKingSq, occupied);
            kingThreats |= pos.pieceTypeBB[Piece.WPAWN] & BitBoard.bPawnAttacks[pos.bKingSq];
            ulong validTargets = 0;
            if ((kingThreats != 0) && ((kingThreats & (kingThreats-1)) == 0)) { // Exactly one attacking piece
                int threatSq = BitBoard.numberOfTrailingZeros(kingThreats);
                validTargets = kingThreats | BitBoard.squaresBetween[pos.bKingSq][threatSq];
            }
            validTargets |= pos.pieceTypeBB[Piece.WKING];
            // Queen moves
            ulong squares = pos.pieceTypeBB[Piece.BQUEEN];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = (BitBoard.rookAttacks(sq, occupied) | BitBoard.bishopAttacks(sq, occupied)) &
                            ~pos.blackBB & validTargets;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Rook moves
            squares = pos.pieceTypeBB[Piece.BROOK];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.rookAttacks(sq, occupied) & ~pos.blackBB & validTargets;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // Bishop moves
            squares = pos.pieceTypeBB[Piece.BBISHOP];
            while (squares != 0) {
                sq = BitBoard.numberOfTrailingZeros(squares);
                m = BitBoard.bishopAttacks(sq, occupied) & ~pos.blackBB & validTargets;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                squares &= squares-1;
            }

            // King moves
            {
                sq = pos.getKingSq(false);
                m = BitBoard.kingAttacks[sq] & ~pos.blackBB;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
            }

            // Knight moves
            ulong knights = pos.pieceTypeBB[Piece.BKNIGHT];
            while (knights != 0) {
                sq = BitBoard.numberOfTrailingZeros(knights);
                m = BitBoard.knightAttacks[sq] & ~pos.blackBB & validTargets;
                if (addMovesByMask(moveList, pos, sq, m)) return moveList;
                knights &= knights-1;
            }

            // Pawn moves
            ulong pawns = pos.pieceTypeBB[Piece.BPAWN];
            m = (pawns >> 8) & ~occupied;
            if (addPawnMovesByMask(moveList, pos, m & validTargets, 8, true)) return moveList;
            m = ((m & BitBoard.maskRow6) >> 8) & ~occupied;
            addPawnDoubleMovesByMask(moveList, pos, m & validTargets, 16);

            int epSquare = pos.getEpSquare();
            ulong epMask = (epSquare >= 0) ? (1UL << epSquare) : 0L;
            m = (pawns >> 9) & BitBoard.maskAToGFiles & ((pos.whiteBB & validTargets) | epMask);
            if (addPawnMovesByMask(moveList, pos, m, 9, true)) return moveList;

            m = (pawns >> 7) & BitBoard.maskBToHFiles & ((pos.whiteBB & validTargets) | epMask);
            if (addPawnMovesByMask(moveList, pos, m, 7, true)) return moveList;
            }

            return moveList;
        }
Beispiel #9
0
 /**
  * Return true if the side to move is in check.
  */
 public static bool inCheck(Position pos)
 {
     int kingSq = pos.getKingSq(pos.whiteMove);
     return sqAttacked(pos, kingSq);
 }