This patch reuses the threatenedPieces variable (which is calculated in movepicker)
to reduce less in the search tree the moves which escape a capture.
passed STC:
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 314352 W: 84042 L: 83328 D: 146982
Ptnml(0-2): 1105, 35084, 84207, 35552, 1228
https://tests.stockfishchess.org/tests/view/
63355f37a004bed9a2e4a17f
passed LTC:
LLR: 2.95 (-2.94,2.94) <0.50,2.50>
Total: 90752 W: 24556 L: 24147 D: 42049
Ptnml(0-2): 59, 8855, 27123, 9296, 43
https://tests.stockfishchess.org/tests/view/
63383a7735f43d649ff5fa8b
closes https://github.com/official-stockfish/Stockfish/pull/4181
bench:
4114228
Color stm = pos.side_to_move();
Value psq = pos.psq_eg_stm();
- // We use the much less accurate but faster Classical eval when the NNUE
+ // We use the much less accurate but faster Classical eval when the NNUE
// option is set to false. Otherwise we use the NNUE eval unless the
// PSQ advantage is decisive and several pieces remain (~3 Elo)
bool useClassical = !useNNUE || (pos.count<ALL_PIECES>() > 7 && abs(psq) > 1760);
stage = (pos.checkers() ? EVASION_TT : MAIN_TT) +
!(ttm && pos.pseudo_legal(ttm));
+ threatenedPieces = 0;
}
/// MovePicker constructor for quiescence search
static_assert(Type == CAPTURES || Type == QUIETS || Type == EVASIONS, "Wrong type");
- [[maybe_unused]] Bitboard threatened, threatenedByPawn, threatenedByMinor, threatenedByRook;
+ [[maybe_unused]] Bitboard threatenedByPawn, threatenedByMinor, threatenedByRook;
if constexpr (Type == QUIETS)
{
Color us = pos.side_to_move();
- // squares threatened by pawns
+
threatenedByPawn = pos.attacks_by<PAWN>(~us);
- // squares threatened by minors or pawns
threatenedByMinor = pos.attacks_by<KNIGHT>(~us) | pos.attacks_by<BISHOP>(~us) | threatenedByPawn;
- // squares threatened by rooks, minors or pawns
threatenedByRook = pos.attacks_by<ROOK>(~us) | threatenedByMinor;
- // pieces threatened by pieces of lesser material value
- threatened = (pos.pieces(us, QUEEN) & threatenedByRook)
- | (pos.pieces(us, ROOK) & threatenedByMinor)
- | (pos.pieces(us, KNIGHT, BISHOP) & threatenedByPawn);
+ // Pieces threatened by pieces of lesser material value
+ threatenedPieces = (pos.pieces(us, QUEEN) & threatenedByRook)
+ | (pos.pieces(us, ROOK) & threatenedByMinor)
+ | (pos.pieces(us, KNIGHT, BISHOP) & threatenedByPawn);
}
for (auto& m : *this)
+ (*continuationHistory[1])[pos.moved_piece(m)][to_sq(m)]
+ (*continuationHistory[3])[pos.moved_piece(m)][to_sq(m)]
+ (*continuationHistory[5])[pos.moved_piece(m)][to_sq(m)]
- + (threatened & from_sq(m) ?
+ + (threatenedPieces & from_sq(m) ?
(type_of(pos.moved_piece(m)) == QUEEN && !(to_sq(m) & threatenedByRook) ? 50000
: type_of(pos.moved_piece(m)) == ROOK && !(to_sq(m) & threatenedByMinor) ? 25000
: !(to_sq(m) & threatenedByPawn) ? 15000
MovePicker(const Position&, Move, Value, Depth, const CapturePieceToHistory*);
Move next_move(bool skipQuiets = false);
+ Bitboard threatenedPieces;
+
private:
template<PickType T, typename Pred> Move select(Pred);
template<GenType> void score();
&& depth < 8
&& eval - futility_margin(depth, improving) - (ss-1)->statScore / 303 >= beta
&& eval >= beta
- && eval < 28031) // larger than VALUE_KNOWN_WIN, but smaller than TB wins.
+ && eval < 28031) // larger than VALUE_KNOWN_WIN, but smaller than TB wins
return eval;
// Step 9. Null move search with verification search (~22 Elo)
if (singularQuietLMR)
r--;
- // Increase reduction if next ply has a lot of fail high else reset count to 0
+ // Dicrease reduction if we move a threatened piece (~1 Elo)
+ if ( depth > 9
+ && (mp.threatenedPieces & from_sq(move)))
+ r--;
+
+ // Increase reduction if next ply has a lot of fail high
if ((ss+1)->cutoffCnt > 3 && !PvNode)
r++;
mainHistory.fill(0);
captureHistory.fill(0);
previousDepth = 0;
-
+
for (bool inCheck : { false, true })
for (StatsType c : { NoCaptures, Captures })
{
/// UCI::loop() waits for a command from the stdin, parses it and then calls the appropriate
/// function. It also intercepts an end-of-file (EOF) indication from the stdin to ensure a
-/// graceful exit if the GUI dies unexpectedly. When called with some command-line arguments,
+/// graceful exit if the GUI dies unexpectedly. When called with some command-line arguments,
/// like running 'bench', the function returns immediately after the command is executed.
/// In addition to the UCI ones, some additional debug commands are also supported.
cmd += std::string(argv[i]) + " ";
do {
- if (argc == 1 && !getline(cin, cmd)) // Wait for an input or an end-of-file (EOF) indication
+ if (argc == 1 && !getline(cin, cmd)) // Wait for an input or an end-of-file (EOF) indication
cmd = "quit";
istringstream is(cmd);