Esempio n. 1
0
        public static Bitboard sliding_attack(Square[] deltas, Square sq, Bitboard occupied)
        {
            Bitboard attack = 0;

            for (int i = 0; i < 4; ++i)
            {
                for (Square s = sq + deltas[i];
                     Types.is_ok_square(s) && BitBoard.square_distance(s, s - deltas[i]) == 1;
                     s += deltas[i])
                {
                    attack |= SquareBB[s];

                    if ((occupied & SquareBB[s]) != 0)
                    {
                        break;
                    }
                }
            }

            return(attack);
        }
Esempio n. 2
0
        /// Bitboards::init() initializes various bitboard tables. It is called at
        /// startup and relies on global objects to be already zero-initialized.
        public static void init()
        {
            for (Square s = SquareS.SQ_A1; s <= SquareS.SQ_H8; ++s)
            {
                BSFTable[bsf_index(SquareBB[s] = 1UL << s)] = s;
            }

            for (Bitboard b = 1; b < 256; ++b)
            {
                MS1BTable[b] = more_than_one(b) ? MS1BTable[b - 1] : lsb(b);
            }

            for (File f = FileS.FILE_A; f <= FileS.FILE_H; ++f)
            {
                FileBB[f] = f > FileS.FILE_A ? FileBB[f - 1] << 1 : FileABB;
            }

            for (Rank r = RankS.RANK_1; r <= RankS.RANK_8; ++r)
            {
                RankBB[r] = r > RankS.RANK_1 ? RankBB[r - 1] << 8 : Rank1BB;
            }

            for (File f = FileS.FILE_A; f <= FileS.FILE_H; ++f)
            {
                AdjacentFilesBB[f] = (f > FileS.FILE_A ? FileBB[f - 1] : 0) | (f < FileS.FILE_H ? FileBB[f + 1] : 0);
            }

            for (int c = ColorS.WHITE; c <= ColorS.BLACK; c++)
            {
                InFrontBB[c] = new Bitboard[RankS.RANK_NB];
            }

            for (Rank r = RankS.RANK_1; r < RankS.RANK_8; ++r)
            {
                InFrontBB[ColorS.WHITE][r] = ~(InFrontBB[ColorS.BLACK][r + 1] = InFrontBB[ColorS.BLACK][r] | RankBB[r]);
            }

            for (int c = ColorS.WHITE; c <= ColorS.BLACK; c++)
            {
                ForwardBB[c]      = new Bitboard[SquareS.SQUARE_NB];
                PawnAttackSpan[c] = new Bitboard[SquareS.SQUARE_NB];
                PassedPawnMask[c] = new Bitboard[SquareS.SQUARE_NB];
            }

            for (Color c = ColorS.WHITE; c <= ColorS.BLACK; ++c)
            {
                for (Square s = SquareS.SQ_A1; s <= SquareS.SQ_H8; ++s)
                {
                    ForwardBB[c][s]      = InFrontBB[c][Types.rank_of(s)] & FileBB[Types.file_of(s)];
                    PawnAttackSpan[c][s] = InFrontBB[c][Types.rank_of(s)] & AdjacentFilesBB[Types.file_of(s)];
                    PassedPawnMask[c][s] = ForwardBB[c][s] | PawnAttackSpan[c][s];
                }
            }

            for (Square c = 0; c < SquareS.SQUARE_NB; c++)
            {
                SquareDistance[c]  = new int[SquareS.SQUARE_NB];
                DistanceRingsBB[c] = new Bitboard[8];
            }

            for (Square s1 = SquareS.SQ_A1; s1 <= SquareS.SQ_H8; ++s1)
            {
                for (Square s2 = SquareS.SQ_A1; s2 <= SquareS.SQ_H8; ++s2)
                {
                    if (s1 != s2)
                    {
                        SquareDistance[s1][s2] = Math.Max(file_distance(s1, s2), rank_distance(s1, s2));
                        DistanceRingsBB[s1][SquareDistance[s1][s2] - 1] |= SquareBB[s2];
                    }
                }
            }

            int[][] steps = new int[7][];
            steps[0] = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            steps[1] = new int[] { 7, 9, 0, 0, 0, 0, 0, 0, 0 };
            steps[2] = new int[] { 17, 15, 10, 6, -6, -10, -15, -17, 0 };
            steps[3] = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            steps[4] = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            steps[5] = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            steps[6] = new int[] { 9, 7, -7, -9, 8, 1, -1, -8, 0 };

            for (Piece p = PieceS.NO_PIECE; p < PieceS.PIECE_NB; p++)
            {
                StepAttacksBB[p] = new Bitboard[SquareS.SQUARE_NB];
            }

            for (Color c = ColorS.WHITE; c <= ColorS.BLACK; ++c)
            {
                for (PieceType pt = PieceTypeS.PAWN; pt <= PieceTypeS.KING; ++pt)
                {
                    for (Square s = SquareS.SQ_A1; s <= SquareS.SQ_H8; ++s)
                    {
                        for (int i = 0; steps[pt][i] != 0; ++i)
                        {
                            Square to = s + (Square)(c == ColorS.WHITE ? steps[pt][i] : -steps[pt][i]);

                            if (Types.is_ok_square(to) && BitBoard.square_distance(s, to) < 3)
                            {
                                StepAttacksBB[Types.make_piece(c, pt)][s] |= SquareBB[to];
                            }
                        }
                    }
                }
            }


            Square[] RDeltas = new Square[] { SquareS.DELTA_N, SquareS.DELTA_E, SquareS.DELTA_S, SquareS.DELTA_W };
            Square[] BDeltas = new Square[] { SquareS.DELTA_NE, SquareS.DELTA_SE, SquareS.DELTA_SW, SquareS.DELTA_NW };

            init_magics(PieceTypeS.ROOK, RAttacks, RMagics, RMasks, RShifts, RDeltas, magic_index);
            init_magics(PieceTypeS.BISHOP, BAttacks, BMagics, BMasks, BShifts, BDeltas, magic_index);

            for (PieceType pt = PieceTypeS.NO_PIECE_TYPE; pt < PieceTypeS.PIECE_TYPE_NB; pt++)
            {
                PseudoAttacks[pt] = new Bitboard[SquareS.SQUARE_NB];
            }

            for (Square s = SquareS.SQ_A1; s <= SquareS.SQ_H8; s++)
            {
                BetweenBB[s] = new Bitboard[SquareS.SQUARE_NB];
                LineBB[s]    = new Bitboard[SquareS.SQUARE_NB];
            }

            for (Square s1 = SquareS.SQ_A1; s1 <= SquareS.SQ_H8; ++s1)
            {
                PseudoAttacks[PieceTypeS.QUEEN][s1]  = PseudoAttacks[PieceTypeS.BISHOP][s1] = attacks_bb_SBBPT(s1, 0, PieceTypeS.BISHOP);
                PseudoAttacks[PieceTypeS.QUEEN][s1] |= PseudoAttacks[PieceTypeS.ROOK][s1] = attacks_bb_SBBPT(s1, 0, PieceTypeS.ROOK);

                for (Square s2 = SquareS.SQ_A1; s2 <= SquareS.SQ_H8; ++s2)
                {
                    Piece pc = (PseudoAttacks[PieceTypeS.BISHOP][s1] & SquareBB[s2]) != 0 ? PieceS.W_BISHOP :
                               (PseudoAttacks[PieceTypeS.ROOK][s1] & SquareBB[s2]) != 0 ? PieceS.W_ROOK : PieceS.NO_PIECE;

                    if (pc == PieceS.NO_PIECE)
                    {
                        continue;
                    }

                    LineBB[s1][s2]    = (attacks_bb_PSBB(pc, s1, 0) & attacks_bb_PSBB(pc, s2, 0)) | SquareBB[s1] | SquareBB[s2];
                    BetweenBB[s1][s2] = attacks_bb_PSBB(pc, s1, SquareBB[s2]) & attacks_bb_PSBB(pc, s2, SquareBB[s1]);
                }
            }
        }