uint8_t PopCnt16[1 << 16];
uint8_t SquareDistance[SQUARE_NB][SQUARE_NB];
- Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
Bitboard LineBB[SQUARE_NB][SQUARE_NB];
-Bitboard DistanceRingBB[SQUARE_NB][8];
-Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB];
-Bitboard PawnAttacks[COLOR_NB][SQUARE_NB];
+Bitboard DistanceRingBB[SQUARE_NB][FILE_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 SquareBB[SQUARE_NB];
+Bitboard BoardSizeBB[FILE_NB][RANK_NB];
Bitboard KingFlank[FILE_NB] = {
QueenSide ^ FileDBB, QueenSide, QueenSide,
DistanceRingBB[s1][SquareDistance[s1][s2]] |= s2;
}
- int steps[][5] = { {}, { 7, 9 }, { 6, 10, 15, 17 }, {}, {}, {}, { 1, 7, 8, 9 } };
+ // Piece moves
+ Direction RookDirections[5] = { NORTH, EAST, SOUTH, WEST };
+ Direction BishopDirections[5] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
+
+#ifdef PRECOMPUTED_MAGICS
+ init_magics(RookTable, RookMagics, RookDirections, RookMagicInit);
+ init_magics(BishopTable, BishopMagics, BishopDirections, BishopMagicInit);
+#else
+ init_magics(RookTable, RookMagics, RookDirections);
+ init_magics(BishopTable, BishopMagics, BishopDirections);
+#endif
+
+ int stepsCapture[][13] = {
+ {}, // NO_PIECE_TYPE
+ { NORTH_WEST, NORTH_EAST }, // pawn
+ { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // knight
+ {}, // bishop
+ {}, // rook
+ {}, // queen
+ { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST }, // fers/met
+ { 2 * SOUTH_WEST, 2 * SOUTH_EAST, 2 * NORTH_WEST, 2 * NORTH_EAST }, // alfil
+ { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH, NORTH_EAST }, // silver/khon
+ { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH_WEST, SOUTH_EAST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH_WEST, NORTH_EAST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // aiwok
+ { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST }, // bers/dragon
+ { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // archbishop
+ { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // chancellor
+ { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // amazon
+ {}, // knibis
+ { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // biskni
+ { NORTH }, // shogi pawn
+ {}, // lance
+ { 2 * NORTH + WEST, 2 * NORTH + EAST }, // shogi knight
+ { WEST, EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // euroshogi knight
+ { SOUTH, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST }, // gold
+ { SOUTH, WEST, EAST, NORTH }, // horse
+ { SOUTH, WEST, EAST, NORTH }, // clobber
+ { NORTH_WEST, NORTH_EAST }, // breakthrough
+ {}, // immobile
+ { SOUTH, WEST, EAST, NORTH }, // wazir
+ { SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST }, // commoner
+ { SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST } // king
+ };
+ int stepsQuiet[][13] = {
+ {}, // NO_PIECE_TYPE
+ { NORTH }, // pawn
+ { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // knight
+ {}, // bishop
+ {}, // rook
+ {}, // queen
+ { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST }, // fers/met
+ { 2 * SOUTH_WEST, 2 * SOUTH_EAST, 2 * NORTH_WEST, 2 * NORTH_EAST }, // alfil
+ { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH, NORTH_EAST }, // silver/khon
+ { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH_WEST, SOUTH_EAST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH_WEST, NORTH_EAST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // aiwok
+ { SOUTH_WEST, SOUTH_EAST, NORTH_WEST, NORTH_EAST }, // bers/dragon
+ { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // archbishop
+ { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // chancellor
+ { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // amazon
+ { 2 * SOUTH + WEST, 2 * SOUTH + EAST, SOUTH + 2 * WEST, SOUTH + 2 * EAST,
+ NORTH + 2 * WEST, NORTH + 2 * EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // knibis
+ {}, // biskni
+ { NORTH }, // shogi pawn
+ {}, // lance
+ { 2 * NORTH + WEST, 2 * NORTH + EAST }, // shogi knight
+ { WEST, EAST, 2 * NORTH + WEST, 2 * NORTH + EAST }, // euroshogi knight
+ { SOUTH, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST }, // gold
+ { SOUTH, WEST, EAST, NORTH }, // horse
+ {}, // clobber
+ { NORTH_WEST, NORTH, NORTH_EAST }, // breakthrough
+ {}, // immobile
+ { SOUTH, WEST, EAST, NORTH }, // wazir
+ { SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST }, // commoner
+ { SOUTH_WEST, SOUTH, SOUTH_EAST, WEST, EAST, NORTH_WEST, NORTH, NORTH_EAST } // king
+ };
+ Direction sliderCapture[][9] = {
+ {}, // NO_PIECE_TYPE
+ {}, // pawn
+ {}, // knight
+ { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // bishop
+ { NORTH, EAST, SOUTH, WEST }, // rook
+ { NORTH, EAST, SOUTH, WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // queen
+ {}, // fers/met
+ {}, // alfil
+ {}, // silver/khon
+ { NORTH, EAST, SOUTH, WEST }, // aiwok
+ { NORTH, EAST, SOUTH, WEST }, // bers/dragon
+ { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // archbishop
+ { NORTH, EAST, SOUTH, WEST }, // chancellor
+ { NORTH, EAST, SOUTH, WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // amazon
+ { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // knibis
+ {}, // biskni
+ {}, // shogi pawn
+ { NORTH }, // lance
+ {}, // shogi knight
+ {}, // euroshogi knight
+ {}, // gold
+ { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // horse
+ {}, // clobber
+ {}, // breakthrough
+ {}, // immobile
+ {}, // wazir
+ {}, // commoner
+ {} // king
+ };
+ Direction sliderQuiet[][9] = {
+ {}, // NO_PIECE_TYPE
+ {}, // pawn
+ {}, // knight
+ { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // bishop
+ { NORTH, EAST, SOUTH, WEST }, // rook
+ { NORTH, EAST, SOUTH, WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // queen
+ {}, // fers/met
+ {}, // alfil
+ {}, // silver/khon
+ { NORTH, EAST, SOUTH, WEST }, // aiwok
+ { NORTH, EAST, SOUTH, WEST }, // bers/dragon
+ { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // archbishop
+ { NORTH, EAST, SOUTH, WEST }, // chancellor
+ { NORTH, EAST, SOUTH, WEST, NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // amazon
+ {}, // knibis
+ { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // biskni
+ {}, // shogi pawn
+ { NORTH }, // lance
+ {}, // shogi knight
+ {}, // euroshogi knight
+ {}, // gold
+ { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST }, // horse
+ {}, // clobber
+ {}, // breakthrough
+ {}, // immobile
+ {}, // wazir
+ {}, // commoner
+ {} // king
+ };
+ int sliderDistCapture[] = {
+ 0, // NO_PIECE_TYPE
+ 0, // pawn
+ 0, // knight
+ FILE_MAX, // bishop
+ FILE_MAX, // rook
+ FILE_MAX, // queen
+ 0, // fers/met
+ 0, // alfil
+ 0, // silver/khon
+ FILE_MAX, // aiwok
+ FILE_MAX, // bers/dragon
+ FILE_MAX, // archbishop
+ FILE_MAX, // chancellor
+ FILE_MAX, // amazon
+ FILE_MAX, // knibis
+ 0, // biskni
+ 0, // shogi pawn
+ FILE_MAX, // lance
+ 0, // shogi knight
+ 0, // euroshogi knight
+ 0, // gold
+ FILE_MAX, // horse
+ 0, // clobber
+ 0, // breakthrough
+ 0, // immobile
+ 0, // wazir
+ 0, // commoner
+ 0 // king
+ };
+ int sliderDistQuiet[] = {
+ 0, // NO_PIECE_TYPE
+ 0, // pawn
+ 0, // knight
+ FILE_MAX, // bishop
+ FILE_MAX, // rook
+ FILE_MAX, // queen
+ 0, // fers/met
+ 0, // alfil
+ 0, // silver/khon
+ FILE_MAX, // aiwok
+ FILE_MAX, // bers/dragon
+ FILE_MAX, // archbishop
+ FILE_MAX, // chancellor
+ FILE_MAX, // amazon
+ 0, // knibis
+ FILE_MAX, // biskni
+ 0, // shogi pawn
+ FILE_MAX, // lance
+ 0, // shogi knight
+ 0, // euroshogi knight
+ 0, // gold
+ FILE_MAX, // horse
+ 0, // clobber
+ 0, // breakthrough
+ 0, // immobile
+ 0, // wazir
+ 0, // commoner
+ 0 // king
+ };
for (Color c = WHITE; c <= BLACK; ++c)
- for (PieceType pt : { PAWN, KNIGHT, KING })
- for (Square s = SQ_A1; s <= SQ_H8; ++s)
- for (int i = 0; steps[pt][i]; ++i)
+ for (PieceType pt = PAWN; pt <= KING; ++pt)
+ for (Square s = SQ_A1; s <= SQ_MAX; ++s)
+ {
+ for (int i = 0; stepsCapture[pt][i]; ++i)
{
- Square to = s + Direction(c == WHITE ? steps[pt][i] : -steps[pt][i]);
+ Square to = s + Direction(c == WHITE ? stepsCapture[pt][i] : -stepsCapture[pt][i]);
- if (is_ok(to) && distance(s, to) < 3)
+ if (is_ok(to) && distance(s, to) < 4)
{
- if (pt == PAWN)
- PawnAttacks[c][s] |= to;
- else
- PseudoAttacks[pt][s] |= to;
+ PseudoAttacks[c][pt][s] |= to;
+ LeaperAttacks[c][pt][s] |= to;
}
}
+ for (int i = 0; stepsQuiet[pt][i]; ++i)
+ {
+ Square to = s + Direction(c == WHITE ? stepsQuiet[pt][i] : -stepsQuiet[pt][i]);
- Direction RookDirections[] = { NORTH, EAST, SOUTH, WEST };
- Direction BishopDirections[] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
-
- init_magics(RookTable, RookMagics, RookDirections);
- init_magics(BishopTable, BishopMagics, BishopDirections);
+ if (is_ok(to) && distance(s, to) < 4)
+ {
+ PseudoMoves[c][pt][s] |= to;
+ LeaperMoves[c][pt][s] |= to;
+ }
+ }
+ PseudoAttacks[c][pt][s] |= sliding_attack(sliderCapture[pt], s, 0, sliderDistCapture[pt], c);
+ PseudoMoves[c][pt][s] |= sliding_attack(sliderQuiet[pt], s, 0, sliderDistQuiet[pt], c);
+ }
- for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
+ for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1)
{
- 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)
- if (PseudoAttacks[pt][s1] & s2)
- LineBB[s1][s2] = (attacks_bb(pt, s1, 0) & attacks_bb(pt, s2, 0)) | s1 | s2;
+ for (Square s2 = SQ_A1; s2 <= SQ_MAX; ++s2)
+ if (PseudoAttacks[WHITE][pt][s1] & s2)
- {
+ 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));
- }
}
}