From f436bf77ad2eb42228747d9aa58eeb7403e23d49 Mon Sep 17 00:00:00 2001 From: disservin <45608332+Disservin@users.noreply.github.com> Date: Sun, 18 Sep 2022 11:16:54 +0200 Subject: [PATCH] Use less reduction for escaping moves 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 --- src/evaluate.cpp | 2 +- src/movepick.cpp | 17 ++++++++--------- src/movepick.h | 2 ++ src/search.cpp | 9 +++++++-- src/thread.cpp | 2 +- src/uci.cpp | 4 ++-- 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 0657088f..85700bcc 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -1054,7 +1054,7 @@ Value Eval::evaluate(const Position& pos, int* complexity) { 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() > 7 && abs(psq) > 1760); diff --git a/src/movepick.cpp b/src/movepick.cpp index e10454b0..3428a764 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -69,6 +69,7 @@ MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHist stage = (pos.checkers() ? EVASION_TT : MAIN_TT) + !(ttm && pos.pseudo_legal(ttm)); + threatenedPieces = 0; } /// MovePicker constructor for quiescence search @@ -106,21 +107,19 @@ void MovePicker::score() { 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(~us); - // squares threatened by minors or pawns threatenedByMinor = pos.attacks_by(~us) | pos.attacks_by(~us) | threatenedByPawn; - // squares threatened by rooks, minors or pawns threatenedByRook = pos.attacks_by(~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) @@ -134,7 +133,7 @@ void MovePicker::score() { + (*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 diff --git a/src/movepick.h b/src/movepick.h index 979709ae..55fcc644 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -131,6 +131,8 @@ public: MovePicker(const Position&, Move, Value, Depth, const CapturePieceToHistory*); Move next_move(bool skipQuiets = false); + Bitboard threatenedPieces; + private: template Move select(Pred); template void score(); diff --git a/src/search.cpp b/src/search.cpp index be0f3451..4b6b497a 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -789,7 +789,7 @@ namespace { && 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) @@ -1163,7 +1163,12 @@ moves_loop: // When in check, search starts here 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++; diff --git a/src/thread.cpp b/src/thread.cpp index c834fa9f..288588b0 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -61,7 +61,7 @@ void Thread::clear() { mainHistory.fill(0); captureHistory.fill(0); previousDepth = 0; - + for (bool inCheck : { false, true }) for (StatsType c : { NoCaptures, Captures }) { diff --git a/src/uci.cpp b/src/uci.cpp index ec106ee9..d5e2c2c3 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -224,7 +224,7 @@ namespace { /// 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. @@ -240,7 +240,7 @@ void UCI::loop(int argc, char* argv[]) { 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); -- 2.39.2