uint8_t SquareDistance[SQUARE_NB][SQUARE_NB];
Bitboard LineBB[SQUARE_NB][SQUARE_NB];
- Bitboard DistanceRingBB[SQUARE_NB][FILE_NB];
-Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB];
-Bitboard PawnAttacks[COLOR_NB][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 SquareBB[SQUARE_NB];
+Bitboard BoardSizeBB[FILE_NB][RANK_NB];
Bitboard KingFlank[FILE_NB] = {
QueenSide ^ FileDBB, QueenSide, QueenSide,
for (unsigned i = 0; i < (1 << 16); ++i)
PopCnt16[i] = std::bitset<16>(i).count();
- for (Square s = SQ_A1; s <= SQ_H8; ++s)
- SquareBB[s] = (1ULL << s);
+ for (Square s = SQ_A1; s <= SQ_MAX; ++s)
+ SquareBB[s] = make_bitboard(s);
- for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
- for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
+ 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] : 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));
- DistanceRingBB[s1][SquareDistance[s1][s2]] |= s2;
- }
- int steps[][5] = { {}, { 7, 9 }, { 6, 10, 15, 17 }, {}, {}, {}, { 1, 7, 8, 9 } };
+ // Piece moves
+ std::vector<Direction> RookDirections = { NORTH, EAST, SOUTH, WEST };
+ std::vector<Direction> BishopDirections = { 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
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)
+ {
+ const PieceInfo* pi = pieceMap.find(pt)->second;
+
+ for (Square s = SQ_A1; s <= SQ_MAX; ++s)
+ {
+ for (Direction d : pi->stepsCapture)
{
- Square to = s + Direction(c == WHITE ? steps[pt][i] : -steps[pt][i]);
+ Square to = s + Direction(c == WHITE ? d : -d);
- 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 (Direction d : pi->stepsQuiet)
+ {
+ Square to = s + Direction(c == WHITE ? d : -d);
- 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(pi->sliderCapture, s, 0, c);
+ PseudoMoves[c][pt][s] |= sliding_attack(pi->sliderQuiet, s, 0, 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;
}
}
Square ksq = pos.square<KING>(Us);
kingSquares[Us] = ksq;
castlingRights[Us] = pos.castling_rights(Us);
- int minKingPawnDistance = 0;
Bitboard pawns = pos.pieces(Us, PAWN);
- if (pawns)
- while (!(DistanceRingBB[ksq][++minKingPawnDistance] & pawns)) {}
+ int minPawnDist = pawns ? 8 : 0;
+
- if (pawns & PseudoAttacks[KING][ksq])
++ if (pawns & PseudoAttacks[Us][KING][ksq])
+ minPawnDist = 1;
+
+ else while (pawns)
+ minPawnDist = std::min(minPawnDist, distance(ksq, pop_lsb(&pawns)));
Value bonus = evaluate_shelter<Us>(pos, ksq);
// If we can castle use the bonus after the castling if it is bigger
if (pos.can_castle(Us | KING_SIDE))
- bonus = std::max(bonus, evaluate_shelter<Us>(pos, relative_square(Us, SQ_G1)));
+ {
+ Square s = make_square(pos.castling_kingside_file(), Us == WHITE ? RANK_1 : pos.max_rank());
+ bonus = std::max(bonus, evaluate_shelter<Us>(pos, s));
+ }
if (pos.can_castle(Us | QUEEN_SIDE))
- bonus = std::max(bonus, evaluate_shelter<Us>(pos, relative_square(Us, SQ_C1)));
+ {
+ Square s = make_square(pos.castling_queenside_file(), Us == WHITE ? RANK_1 : pos.max_rank());
+ bonus = std::max(bonus, evaluate_shelter<Us>(pos, s));
+ }
- return make_score(bonus, -16 * minKingPawnDistance);
+ return make_score(bonus, -16 * minPawnDist);
}
// Explicit template instantiation