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); }
/// 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]); } } }