From 1a395f1b565e4140a3f15bdd7b8add92fd11537a Mon Sep 17 00:00:00 2001 From: mstembera Date: Fri, 28 Mar 2025 14:39:11 -0700 Subject: [PATCH] Remove pawn_attacks_bb() Generalize attacks_bb() to handle pawns and remove pawn_attacks_bb() https://tests.stockfishchess.org/tests/view/67e9496231d7cf8afdc44a2e LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 134688 W: 34660 L: 34553 D: 65475 Ptnml(0-2): 298, 14619, 37462, 14608, 357 closes https://github.com/official-stockfish/Stockfish/pull/5947 No functional change --- src/bitboard.cpp | 5 ++--- src/bitboard.h | 12 +++--------- src/movegen.cpp | 2 +- src/position.cpp | 18 +++++++++--------- 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/src/bitboard.cpp b/src/bitboard.cpp index 8798c5701..9b1d674c0 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -32,7 +32,6 @@ uint8_t SquareDistance[SQUARE_NB][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]; alignas(64) Magic Magics[SQUARE_NB][2]; @@ -86,8 +85,8 @@ void Bitboards::init() { for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1) { - PawnAttacks[WHITE][s1] = pawn_attacks_bb(square_bb(s1)); - PawnAttacks[BLACK][s1] = pawn_attacks_bb(square_bb(s1)); + PseudoAttacks[WHITE][s1] = pawn_attacks_bb(square_bb(s1)); + PseudoAttacks[BLACK][s1] = pawn_attacks_bb(square_bb(s1)); for (int step : {-9, -8, -7, -1, 1, 7, 8, 9}) PseudoAttacks[KING][s1] |= safe_destination(s1, step); diff --git a/src/bitboard.h b/src/bitboard.h index df15113bd..941299c0d 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -62,7 +62,6 @@ extern uint8_t SquareDistance[SQUARE_NB][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]; // Magic holds all magic bitboards relevant data for a single square @@ -155,11 +154,6 @@ constexpr Bitboard pawn_attacks_bb(Bitboard b) { : shift(b) | shift(b); } -inline Bitboard pawn_attacks_bb(Color c, Square s) { - - assert(is_ok(s)); - return PawnAttacks[c][s]; -} // Returns a bitboard representing an entire line (from board edge // to board edge) that intersects the two given squares. If the given squares @@ -216,10 +210,10 @@ inline int edge_distance(File f) { return std::min(f, File(FILE_H - f)); } // Returns the pseudo attacks of the given piece type // assuming an empty board. template -inline Bitboard attacks_bb(Square s) { +inline Bitboard attacks_bb(Square s, Color c = COLOR_NB) { - assert((Pt != PAWN) && (is_ok(s))); - return PseudoAttacks[Pt][s]; + assert((Pt != PAWN || c < COLOR_NB) && (is_ok(s))); + return Pt == PAWN ? PseudoAttacks[c][s] : PseudoAttacks[Pt][s]; } diff --git a/src/movegen.cpp b/src/movegen.cpp index 8653a828f..a73bd8501 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -134,7 +134,7 @@ ExtMove* generate_pawn_moves(const Position& pos, ExtMove* moveList, Bitboard ta if (Type == EVASIONS && (target & (pos.ep_square() + Up))) return moveList; - b1 = pawnsNotOn7 & pawn_attacks_bb(Them, pos.ep_square()); + b1 = pawnsNotOn7 & attacks_bb(pos.ep_square(), Them); assert(b1); diff --git a/src/position.cpp b/src/position.cpp index 52e1004e8..02fd6c7a9 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -270,7 +270,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si) { // a) side to move have a pawn threatening epSquare // b) there is an enemy pawn in front of epSquare // c) there is no piece on epSquare or behind epSquare - enpassant = pawn_attacks_bb(~sideToMove, st->epSquare) & pieces(sideToMove, PAWN) + enpassant = attacks_bb(st->epSquare, ~sideToMove) & pieces(sideToMove, PAWN) && (pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove))) && !(pieces() & (st->epSquare | (st->epSquare + pawn_push(sideToMove)))); } @@ -321,7 +321,7 @@ void Position::set_check_info() const { Square ksq = square(~sideToMove); - st->checkSquares[PAWN] = pawn_attacks_bb(~sideToMove, ksq); + st->checkSquares[PAWN] = attacks_bb(ksq, ~sideToMove); st->checkSquares[KNIGHT] = attacks_bb(ksq); st->checkSquares[BISHOP] = attacks_bb(ksq, pieces()); st->checkSquares[ROOK] = attacks_bb(ksq, pieces()); @@ -487,8 +487,8 @@ Bitboard Position::attackers_to(Square s, Bitboard occupied) const { return (attacks_bb(s, occupied) & pieces(ROOK, QUEEN)) | (attacks_bb(s, occupied) & pieces(BISHOP, QUEEN)) - | (pawn_attacks_bb(BLACK, s) & pieces(WHITE, PAWN)) - | (pawn_attacks_bb(WHITE, s) & pieces(BLACK, PAWN)) + | (attacks_bb(s, BLACK) & pieces(WHITE, PAWN)) + | (attacks_bb(s, WHITE) & pieces(BLACK, PAWN)) | (attacks_bb(s) & pieces(KNIGHT)) | (attacks_bb(s) & pieces(KING)); } @@ -498,7 +498,7 @@ bool Position::attackers_to_exist(Square s, Bitboard occupied, Color c) const { && (attacks_bb(s, occupied) & pieces(c, ROOK, QUEEN))) || ((attacks_bb(s) & pieces(c, BISHOP, QUEEN)) && (attacks_bb(s, occupied) & pieces(c, BISHOP, QUEEN))) - || (((pawn_attacks_bb(~c, s) & pieces(PAWN)) | (attacks_bb(s) & pieces(KNIGHT)) + || (((attacks_bb(s, ~c) & pieces(PAWN)) | (attacks_bb(s) & pieces(KNIGHT)) | (attacks_bb(s) & pieces(KING))) & pieces(c)); } @@ -597,9 +597,9 @@ bool Position::pseudo_legal(const Move m) const { if ((Rank8BB | Rank1BB) & to) return false; - if (!(pawn_attacks_bb(us, from) & pieces(~us) & to) // Not a capture - && !((from + pawn_push(us) == to) && empty(to)) // Not a single push - && !((from + 2 * pawn_push(us) == to) // Not a double push + if (!(attacks_bb(from, us) & pieces(~us) & to) // Not a capture + && !((from + pawn_push(us) == to) && empty(to)) // Not a single push + && !((from + 2 * pawn_push(us) == to) // Not a double push && (relative_rank(us, from) == RANK_2) && empty(to) && empty(to - pawn_push(us)))) return false; } @@ -812,7 +812,7 @@ DirtyPiece Position::do_move(Move m, { // Set en passant square if the moved pawn can be captured if ((int(to) ^ int(from)) == 16 - && (pawn_attacks_bb(us, to - pawn_push(us)) & pieces(them, PAWN))) + && (attacks_bb(to - pawn_push(us), us) & pieces(them, PAWN))) { st->epSquare = to - pawn_push(us); k ^= Zobrist::enpassant[file_of(st->epSquare)];