diff --git a/src/nnue/features/full_threats.cpp b/src/nnue/features/full_threats.cpp index 4cd0cc77c..6761fe63e 100644 --- a/src/nnue/features/full_threats.cpp +++ b/src/nnue/features/full_threats.cpp @@ -212,6 +212,10 @@ void FullThreats::append_active_indices(Color perspective, const Position& pos, const Bitboard occupied = pos.pieces(); const Bitboard pawns = pos.pieces(PAWN); + const Bitboard pawnTargets = pos.pieces(PAWN, KNIGHT, ROOK); + const Bitboard minorSliderTargets = pos.pieces(PAWN, KNIGHT, BISHOP, ROOK); + const Bitboard queenTargets = pos.pieces(PAWN, KNIGHT, BISHOP, ROOK, QUEEN); + for (Color color : {WHITE, BLACK}) { const Color c = Color(perspective ^ color); @@ -236,14 +240,14 @@ void FullThreats::append_active_indices(Color perspective, const Position& pos, if (c == WHITE) { - process_pawn_attacks(shift(cPawns) & occupied, NORTH_EAST); - process_pawn_attacks(shift(cPawns) & occupied, NORTH_WEST); + process_pawn_attacks(shift(cPawns) & pawnTargets, NORTH_EAST); + process_pawn_attacks(shift(cPawns) & pawnTargets, NORTH_WEST); process_pawn_attacks(shift(pushers), NORTH); } else { - process_pawn_attacks(shift(cPawns) & occupied, SOUTH_WEST); - process_pawn_attacks(shift(cPawns) & occupied, SOUTH_EAST); + process_pawn_attacks(shift(cPawns) & pawnTargets, SOUTH_WEST); + process_pawn_attacks(shift(cPawns) & pawnTargets, SOUTH_EAST); process_pawn_attacks(shift(pushers), SOUTH); } } @@ -255,7 +259,8 @@ void FullThreats::append_active_indices(Color perspective, const Position& pos, while (bb) { Square from = pop_lsb(bb); - Bitboard attacks = Attacks::attacks_bb(pt, from, occupied) & occupied; + Bitboard targets = pt == KNIGHT || pt == QUEEN ? queenTargets : minorSliderTargets; + Bitboard attacks = Attacks::attacks_bb(pt, from, occupied) & targets; while (attacks) { Square to = pop_lsb(attacks); diff --git a/src/position.cpp b/src/position.cpp index a70acd6c1..b9c6eeaac 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1167,6 +1167,10 @@ void write_multiple_dirties(const Position& p, } #endif +constexpr bool can_slider_threat(Piece pc, Piece slider) { + return type_of(pc) != QUEEN || type_of(slider) == QUEEN; +} + template void Position::update_piece_threats(Piece pc, bool putPiece, @@ -1179,11 +1183,12 @@ void Position::update_piece_threats(Piece pc, const Bitboard bishopQueens = pieces(BISHOP, QUEEN); const Bitboard rAttacks = attacks_bb(s, occupied); const Bitboard bAttacks = attacks_bb(s, occupied); - const Bitboard kings = pieces(KING); - Bitboard occupiedNoK = occupied ^ kings; + const Bitboard occupiedNoK = occupied ^ pieces(KING); - Bitboard sliders = (rookQueens & rAttacks) | (bishopQueens & bAttacks); - auto process_sliders = [&](bool addDirectAttacks) { + Bitboard sliders = (rookQueens & rAttacks) | (bishopQueens & bAttacks); + Bitboard directSliders = type_of(pc) == QUEEN ? sliders & pieces(QUEEN) : sliders; + + auto process_sliders = [&](bool addDirectAttacks) { while (sliders) { Square sliderSq = pop_lsb(sliders); @@ -1197,10 +1202,11 @@ void Position::update_piece_threats(Piece pc, { const Square threatenedSq = lsb(discovered); const Piece threatenedPc = piece_on(threatenedSq); - add_dirty_threat(dts, !putPiece, slider, threatenedPc, sliderSq, threatenedSq); + if (can_slider_threat(threatenedPc, slider)) + add_dirty_threat(dts, !putPiece, slider, threatenedPc, sliderSq, threatenedSq); } - if (addDirectAttacks) + if (addDirectAttacks && can_slider_threat(pc, slider)) add_dirty_threat(dts, putPiece, slider, pc, sliderSq, s); } }; @@ -1218,12 +1224,12 @@ void Position::update_piece_threats(Piece pc, const Bitboard blackPawns = pieces(BLACK, PAWN); - Bitboard threatened = attacks_bb(pc, s, occupied) & occupiedNoK; - Bitboard incoming_threats = - (PseudoAttacks[KNIGHT][s] & knights) | (PseudoAttacks[KING][s] & kings); + Bitboard threatened = attacks_bb(pc, s, occupied) & occupiedNoK; + Bitboard incoming_threats = PseudoAttacks[KNIGHT][s] & knights; // Compute both incoming and outgoing pawn threats. Incoming pawn pushers are only // added if 'pc' is a pawn. + Bitboard pawnThreats = 0; if (type_of(pc) == PAWN) { Bitboard whiteAttacks = PawnPushOrAttacks[WHITE][s]; @@ -1231,21 +1237,38 @@ void Position::update_piece_threats(Piece pc, threatened |= (color_of(pc) == WHITE ? whiteAttacks : blackAttacks) & pieces(PAWN); - incoming_threats |= whiteAttacks & blackPawns; - incoming_threats |= blackAttacks & whitePawns; + pawnThreats = whiteAttacks & blackPawns; + pawnThreats |= blackAttacks & whitePawns; } else { - incoming_threats |= + pawnThreats = (attacks_bb(s, WHITE) & blackPawns) | (attacks_bb(s, BLACK) & whitePawns); } + if (type_of(pc) == PAWN || type_of(pc) == KNIGHT || type_of(pc) == ROOK) + incoming_threats |= pawnThreats; + + switch (type_of(pc)) + { + case PAWN : + threatened &= pieces(PAWN, KNIGHT, ROOK); + break; + case BISHOP : + case ROOK : + threatened &= pieces(PAWN, KNIGHT, BISHOP, ROOK); + break; + default : + threatened &= occupiedNoK; + break; + } + #ifdef USE_AVX512ICL DirtyThreat dt_template{pc, NO_PIECE, s, Square(0), putPiece}; write_multiple_dirties( *this, threatened, dt_template, dts); - Bitboard all_attackers = sliders | incoming_threats; + Bitboard all_attackers = directSliders | incoming_threats; dt_template = {NO_PIECE, pc, Square(0), s, putPiece}; write_multiple_dirties(*this, all_attackers, @@ -1273,7 +1296,7 @@ void Position::update_piece_threats(Piece pc, } else { - incoming_threats |= sliders; + incoming_threats |= directSliders; } #ifndef USE_AVX512ICL