コード例 #1
0
ファイル: TextIO.cs プロジェクト: Chessforeva/Csharp4chess
 /** Remove pseudo-legal EP square if it is not legal, ie would leave king in check. */
 public static void fixupEPSquare(Position pos)
 {
     int epSquare = pos.getEpSquare();
     if (epSquare >= 0) {
     MoveGen MG = new MoveGen();
     MoveGen.MoveList moves = MG.pseudoLegalMoves(pos);
     MoveGen.RemoveIllegal(pos, moves);
     bool epValid = false;
     for (int mi = 0; mi < moves.size; mi++) {
         Move m = moves.m[mi];
         if (m.to == epSquare) {
             if (pos.getPiece(m.from) == (pos.whiteMove ? Piece.WPAWN : Piece.BPAWN)) {
                 epValid = true;
                 break;
             }
         }
     }
     if (!epValid) {
         pos.setEpSquare(-1);
     }
     }
 }
コード例 #2
0
ファイル: TextIO.cs プロジェクト: Chessforeva/Csharp4chess
 private static bool isCapture(Position pos, Move move)
 {
     if (pos.getPiece(move.to) == Piece.EMPTY) {
     int p = pos.getPiece(move.from);
     if ((p == (pos.whiteMove ? Piece.WPAWN : Piece.BPAWN)) && (move.to == pos.getEpSquare())) {
         return true;
     } else {
         return false;
     }
     } else {
     return true;
     }
 }
コード例 #3
0
ファイル: TextIO.cs プロジェクト: Chessforeva/Csharp4chess
        /** Return a FEN string corresponding to a chess Position object. */
        public static string toFEN(Position pos)
        {
            string ret = "";
            // Piece placement
            for (int r = 7; r >=0; r--) {
            int numEmpty = 0;
            for (int c = 0; c < 8; c++) {
                int p = pos.getPiece(Position.getSquare(c, r));
                if (p == Piece.EMPTY) {
                    numEmpty++;
                } else {
                    if (numEmpty > 0) {
                        ret+=numEmpty.ToString();
                        numEmpty = 0;
                    }
                    switch (p) {
                        case Piece.WKING:   ret+=('K'); break;
                        case Piece.WQUEEN:  ret+=('Q'); break;
                        case Piece.WROOK:   ret+=('R'); break;
                        case Piece.WBISHOP: ret+=('B'); break;
                        case Piece.WKNIGHT: ret+=('N'); break;
                        case Piece.WPAWN:   ret+=('P'); break;
                        case Piece.BKING:   ret+=('k'); break;
                        case Piece.BQUEEN:  ret+=('q'); break;
                        case Piece.BROOK:   ret+=('r'); break;
                        case Piece.BBISHOP: ret+=('b'); break;
                        case Piece.BKNIGHT: ret+=('n'); break;
                        case Piece.BPAWN:   ret+=('p'); break;
                        default: throw new RuntimeException();
                    }
                }
            }
            if (numEmpty > 0) {
                ret += numEmpty.ToString();
            }
            if (r > 0) {
                ret += ('/');
            }
            }
            ret += (pos.whiteMove ? " w " : " b ");

            // Castling rights
            bool anyCastle = false;
            if (pos.h1Castle()) {
            ret += ('K');
            anyCastle = true;
            }
            if (pos.a1Castle()) {
            ret += ('Q');
            anyCastle = true;
            }
            if (pos.h8Castle()) {
            ret += ('k');
            anyCastle = true;
            }
            if (pos.a8Castle()) {
            ret += ('q');
            anyCastle = true;
            }
            if (!anyCastle) {
            ret += ('-');
            }

            // En passant target square
            {
            ret += (' ');
            if (pos.getEpSquare() >= 0) {
                int x = Position.getX(pos.getEpSquare());
                int y = Position.getY(pos.getEpSquare());
                ret += ((char)(x + 'a'));
                ret += ((char)(y + '1'));
            } else {
                ret += ('-');
            }
            }

            // Move counters
            ret += " " + pos.halfMoveClock;
            ret += " " + pos.fullMoveCounter;

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