]> git.sesse.net Git - stockfish/commitdiff
Use less reduction for escaping moves
authordisservin <45608332+Disservin@users.noreply.github.com>
Sun, 18 Sep 2022 09:16:54 +0000 (11:16 +0200)
committerStéphane Nicolet <cassio@free.fr>
Mon, 3 Oct 2022 09:50:31 +0000 (11:50 +0200)
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
src/movepick.cpp
src/movepick.h
src/search.cpp
src/thread.cpp
src/uci.cpp

index 0657088f19c936a66872b23e528518861a60f139..85700bcc60dc2b5d26251c9ebec4d8336a2c6cd9 100644 (file)
@@ -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<ALL_PIECES>() > 7 && abs(psq) > 1760);
index e10454b0d982c9e68df1e89ccafb7c05c73c7962..3428a764f1ad3116d765828a50a4e9a522e16804 100644 (file)
@@ -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<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)
@@ -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
index 979709ae682885baa073488b1e335c701abfc8ea..55fcc6442dc871923400ac2fbd804d1453e0f907 100644 (file)
@@ -131,6 +131,8 @@ public:
   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();
index be0f3451635611df64cfde1517ba2475099026af..4b6b497a5b49b504031519b5fcb8137d6a76d1b9 100644 (file)
@@ -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++;
 
index c834fa9f9dff0bd1ce23bd2f72f3c20c5c1ece01..288588b0ee84cd805f0bc4e52868c91e21a81731 100644 (file)
@@ -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 })
       {
index ec106ee9f40e39fd4492aaeba6516bf387fa0b17..d5e2c2c358600d759c765b5a4467665505c9ec08 100644 (file)
@@ -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);