Bitboard SquareBB[SQUARE_NB];
Bitboard LineBB[SQUARE_NB][SQUARE_NB];
+ Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
-Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB];
-Bitboard PawnAttacks[COLOR_NB][SQUARE_NB];
-
-Magic RookMagics[SQUARE_NB];
+Bitboard PseudoAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
+Bitboard PseudoMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
+Bitboard LeaperAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
+Bitboard LeaperMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
+Bitboard BoardSizeBB[FILE_NB][RANK_NB];
+RiderType AttackRiderTypes[PIECE_TYPE_NB];
+RiderType MoveRiderTypes[PIECE_TYPE_NB];
+
+Magic RookMagicsH[SQUARE_NB];
+Magic RookMagicsV[SQUARE_NB];
Magic BishopMagics[SQUARE_NB];
+Magic CannonMagicsH[SQUARE_NB];
+Magic CannonMagicsV[SQUARE_NB];
+Magic HorseMagics[SQUARE_NB];
+Magic ElephantMagics[SQUARE_NB];
+Magic JanggiElephantMagics[SQUARE_NB];
+Magic CannonDiagMagics[SQUARE_NB];
+Magic NightriderMagics[SQUARE_NB];
+Magic GrasshopperMagicsH[SQUARE_NB];
+Magic GrasshopperMagicsV[SQUARE_NB];
+Magic GrasshopperMagicsD[SQUARE_NB];
+
+Magic* magics[] = {BishopMagics, RookMagicsH, RookMagicsV, CannonMagicsH, CannonMagicsV,
+ HorseMagics, ElephantMagics, JanggiElephantMagics, CannonDiagMagics, NightriderMagics,
+ GrasshopperMagicsH, GrasshopperMagicsV, GrasshopperMagicsD};
namespace {
for (unsigned i = 0; i < (1 << 16); ++i)
PopCnt16[i] = uint8_t(std::bitset<16>(i).count());
- for (Square s = SQ_A1; s <= SQ_H8; ++s)
- SquareBB[s] = (1ULL << s);
-
- for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
- for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
- SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2));
-
- init_magics(ROOK, RookTable, RookMagics);
- init_magics(BISHOP, BishopTable, BishopMagics);
-
- for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
+ for (Square s = SQ_A1; s <= SQ_MAX; ++s)
+ SquareBB[s] = make_bitboard(s);
+
+ for (File f = FILE_A; f <= FILE_MAX; ++f)
+ for (Rank r = RANK_1; r <= RANK_MAX; ++r)
+ BoardSizeBB[f][r] = forward_file_bb(BLACK, make_square(f, r)) | SquareBB[make_square(f, r)] | (f > FILE_A ? BoardSizeBB[f - 1][r] : Bitboard(0));
+
+ for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1)
+ for (Square s2 = SQ_A1; s2 <= SQ_MAX; ++s2)
+ SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2));
+
+#ifdef PRECOMPUTED_MAGICS
+ init_magics<RIDER>(RookTableH, RookMagicsH, RookDirectionsH, RookMagicHInit);
+ init_magics<RIDER>(RookTableV, RookMagicsV, RookDirectionsV, RookMagicVInit);
+ init_magics<RIDER>(BishopTable, BishopMagics, BishopDirections, BishopMagicInit);
+ init_magics<HOPPER>(CannonTableH, CannonMagicsH, RookDirectionsH, CannonMagicHInit);
+ init_magics<HOPPER>(CannonTableV, CannonMagicsV, RookDirectionsV, CannonMagicVInit);
+ init_magics<LAME_LEAPER>(HorseTable, HorseMagics, HorseDirections, HorseMagicInit);
+ init_magics<LAME_LEAPER>(ElephantTable, ElephantMagics, ElephantDirections, ElephantMagicInit);
+ init_magics<LAME_LEAPER>(JanggiElephantTable, JanggiElephantMagics, JanggiElephantDirections, JanggiElephantMagicInit);
+ init_magics<HOPPER>(CannonDiagTable, CannonDiagMagics, BishopDirections, CannonDiagMagicInit);
+ init_magics<RIDER>(NightriderTable, NightriderMagics, HorseDirections, NightriderMagicInit);
+ init_magics<HOPPER>(GrasshopperTableH, GrasshopperMagicsH, GrasshopperDirectionsH, GrasshopperMagicHInit);
+ init_magics<HOPPER>(GrasshopperTableV, GrasshopperMagicsV, GrasshopperDirectionsV, GrasshopperMagicVInit);
+ init_magics<HOPPER>(GrasshopperTableD, GrasshopperMagicsD, GrasshopperDirectionsD, GrasshopperMagicDInit);
+#else
+ init_magics<RIDER>(RookTableH, RookMagicsH, RookDirectionsH);
+ init_magics<RIDER>(RookTableV, RookMagicsV, RookDirectionsV);
+ init_magics<RIDER>(BishopTable, BishopMagics, BishopDirections);
+ init_magics<HOPPER>(CannonTableH, CannonMagicsH, RookDirectionsH);
+ init_magics<HOPPER>(CannonTableV, CannonMagicsV, RookDirectionsV);
+ init_magics<LAME_LEAPER>(HorseTable, HorseMagics, HorseDirections);
+ init_magics<LAME_LEAPER>(ElephantTable, ElephantMagics, ElephantDirections);
+ init_magics<LAME_LEAPER>(JanggiElephantTable, JanggiElephantMagics, JanggiElephantDirections);
+ init_magics<HOPPER>(CannonDiagTable, CannonDiagMagics, BishopDirections);
+ init_magics<RIDER>(NightriderTable, NightriderMagics, HorseDirections);
+ init_magics<HOPPER>(GrasshopperTableH, GrasshopperMagicsH, GrasshopperDirectionsH);
+ init_magics<HOPPER>(GrasshopperTableV, GrasshopperMagicsV, GrasshopperDirectionsV);
+ init_magics<HOPPER>(GrasshopperTableD, GrasshopperMagicsD, GrasshopperDirectionsD);
+#endif
+
+ init_pieces();
+
+ for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1)
{
- PawnAttacks[WHITE][s1] = pawn_attacks_bb<WHITE>(square_bb(s1));
- PawnAttacks[BLACK][s1] = pawn_attacks_bb<BLACK>(square_bb(s1));
-
- for (int step : {-9, -8, -7, -1, 1, 7, 8, 9} )
- PseudoAttacks[KING][s1] |= safe_destination(s1, step);
-
- for (int step : {-17, -15, -10, -6, 6, 10, 15, 17} )
- PseudoAttacks[KNIGHT][s1] |= safe_destination(s1, step);
-
- PseudoAttacks[QUEEN][s1] = PseudoAttacks[BISHOP][s1] = attacks_bb<BISHOP>(s1, 0);
- PseudoAttacks[QUEEN][s1] |= PseudoAttacks[ ROOK][s1] = attacks_bb< ROOK>(s1, 0);
-
for (PieceType pt : { BISHOP, ROOK })
- for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
+ for (Square s2 = SQ_A1; s2 <= SQ_MAX; ++s2)
+ {
- if (PseudoAttacks[pt][s1] & s2)
+ if (PseudoAttacks[WHITE][pt][s1] & s2)
- LineBB[s1][s2] = (attacks_bb(WHITE, pt, s1, 0) & attacks_bb(WHITE, pt, s2, 0)) | s1 | s2;
+ {
- LineBB[s1][s2] = (attacks_bb(pt, s1, 0) & attacks_bb(pt, s2, 0)) | s1 | s2;
- BetweenBB[s1][s2] = (attacks_bb(pt, s1, square_bb(s2)) & attacks_bb(pt, s2, square_bb(s1)));
++ LineBB[s1][s2] = (attacks_bb(WHITE, pt, s1, 0) & attacks_bb(WHITE, pt, s2, 0)) | s1 | s2;
++ BetweenBB[s1][s2] = (attacks_bb(WHITE, pt, s1, square_bb(s2)) & attacks_bb(WHITE, pt, s2, square_bb(s1)));
+ }
+ BetweenBB[s1][s2] |= s2;
+ }
}
}
extern uint8_t SquareDistance[SQUARE_NB][SQUARE_NB];
extern Bitboard SquareBB[SQUARE_NB];
+ extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
extern Bitboard LineBB[SQUARE_NB][SQUARE_NB];
-extern Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB];
-extern Bitboard PawnAttacks[COLOR_NB][SQUARE_NB];
+extern Bitboard PseudoAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
+extern Bitboard PseudoMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
+extern Bitboard LeaperAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
+extern Bitboard LeaperMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
+extern Bitboard SquareBB[SQUARE_NB];
+extern Bitboard BoardSizeBB[FILE_NB][RANK_NB];
+extern RiderType AttackRiderTypes[PIECE_TYPE_NB];
+extern RiderType MoveRiderTypes[PIECE_TYPE_NB];
+#ifdef LARGEBOARDS
+int popcount(Bitboard b); // required for 128 bit pext
+#endif
/// Magic holds all magic bitboards relevant data for a single square
struct Magic {
}
- /// between_bb() returns a bitboard representing squares that are linearly
- /// between the two given squares (excluding the given squares). If the given
- /// squares are not on a same file/rank/diagonal, we return 0. For instance,
- /// between_bb(SQ_C4, SQ_F7) will return a bitboard with squares D5 and E6.
+ /// between_bb(s1, s2) returns a bitboard representing the squares in the semi-open
+ /// segment between the squares s1 and s2 (excluding s1 but including s2). If the
+ /// given squares are not on a same file/rank/diagonal, it returns s2. For instance,
+ /// between_bb(SQ_C4, SQ_F7) will return a bitboard with squares D5, E6 and F7, but
+ /// between_bb(SQ_E6, SQ_F8) will return a bitboard with the square F8. This trick
+ /// allows to generate non-king evasion moves faster: the defending piece must either
+ /// interpose itself to cover the check or capture the checking piece.
inline Bitboard between_bb(Square s1, Square s2) {
- Bitboard b = line_bb(s1, s2) & ((AllSquares << s1) ^ (AllSquares << s2));
- return b & (b - 1); //exclude lsb
+ assert(is_ok(s1) && is_ok(s2));
+ return BetweenBB[s1][s2];
}
+inline Bitboard between_bb(Square s1, Square s2, PieceType pt) {
+ if (pt == HORSE)
+ return PseudoAttacks[WHITE][WAZIR][s2] & PseudoAttacks[WHITE][FERS][s1];
+ else if (pt == JANGGI_ELEPHANT)
+ return (PseudoAttacks[WHITE][WAZIR][s2] & PseudoAttacks[WHITE][ALFIL][s1])
+ | (PseudoAttacks[WHITE][KNIGHT][s2] & PseudoAttacks[WHITE][FERS][s1]);
+ else
+ return between_bb(s1, s2);
+}
+
- /// forward_ranks_bb() returns a bitboard representing the squares on the ranks
- /// in front of the given one, from the point of view of the given color. For instance,
+ /// forward_ranks_bb() returns a bitboard representing the squares on the ranks in
+ /// front of the given one, from the point of view of the given color. For instance,
/// forward_ranks_bb(BLACK, SQ_D3) will return the 16 squares on ranks 1 and 2.
constexpr Bitboard forward_ranks_bb(Color c, Square s) {