コード例 #1
0
ファイル: MoveGen.cs プロジェクト: Chessforeva/Csharp4chess
        /**
         * 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;
        }
コード例 #2
0
ファイル: Evaluate.cs プロジェクト: Chessforeva/Csharp4chess
        /** Score castling ability. */
        private int castleBonus(Position pos)
        {
            if (pos.getCastleMask() == 0) return 0;

            int k1 = kt1b[7*8+6] - kt1b[7*8+4];
            int k2 = kt2b[7*8+6] - kt2b[7*8+4];
            int t1 = qV + 2 * rV + 2 * bV;
            int t2 = rV;
            int t = pos.bMtrl - pos.bMtrlPawns;
            int ks = interpolate(t, t2, k2, t1, k1);

            int castleValue = ks + rt1b[7*8+5] - rt1b[7*8+7];
            if (castleValue <= 0)
            return 0;

            ulong occupied = pos.whiteBB | pos.blackBB;
            int tmp = (int) (occupied & 0x6E);
            if (pos.a1Castle()) tmp |= 1;
            if (pos.h1Castle()) tmp |= (1 << 7);
            int wBonus = (castleValue * castleFactor[tmp]) >> 10;

            tmp = (int) ((occupied >> 56) & 0x6E);
            if (pos.a8Castle()) tmp |= 1;
            if (pos.h8Castle()) tmp |= (1 << 7);
            int bBonus = (castleValue * castleFactor[tmp]) >> 10;

            return wBonus - bBonus;
        }
コード例 #3
0
ファイル: MoveGen.cs プロジェクト: Chessforeva/Csharp4chess
        /** 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;
        }