]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Simplification: use Arctan for the optimism S-curve
[stockfish] / src / search.cpp
index 515cc6ceae163e234b9158a8ef25322c1bb44d72..832501f2f70d94437625b35c836692b63f86c2fa 100644 (file)
@@ -69,7 +69,9 @@ namespace {
   // Razor and futility margins
   const int RazorMargin1 = 590;
   const int RazorMargin2 = 604;
-  Value futility_margin(Depth d) { return Value(150 * d / ONE_PLY); }
+  Value futility_margin(Depth d, bool improving) {
+    return Value((175 - 50 * improving) * d / ONE_PLY);
+  }
 
   // Futility and reductions lookup tables, initialized at startup
   int FutilityMoveCounts[2][16]; // [improving][depth]
@@ -349,10 +351,7 @@ void Thread::search() {
               ct =  Options["Contempt"] * PawnValueEg / 100; // From centipawns
 
               // Adjust contempt based on current bestValue (dynamic contempt)
-              int sign = (bestValue > 0) - (bestValue < 0);
-              ct +=  bestValue >  500 ?  70 :
-                     bestValue < -500 ? -70 :
-                     bestValue / 10 + sign * int(std::round(3.22 * log(1 + abs(bestValue))));
+              ct += int(std::round(48 * atan(float(bestValue) / 128)));
 
               Eval::Contempt = (us == WHITE ?  make_score(ct, ct / 2)
                                             : -make_score(ct, ct / 2));
@@ -678,6 +677,10 @@ namespace {
                   ss->staticEval, TT.generation());
     }
 
+    improving =   ss->staticEval >= (ss-2)->staticEval
+            /* || ss->staticEval == VALUE_NONE Already implicit in the previous condition */
+               ||(ss-2)->staticEval == VALUE_NONE;
+
     if (skipEarlyPruning || !pos.non_pawn_material(pos.side_to_move()))
         goto moves_loop;
 
@@ -702,7 +705,7 @@ namespace {
     // Step 8. Futility pruning: child node (skipped when in check)
     if (   !rootNode
         &&  depth < 7 * ONE_PLY
-        &&  eval - futility_margin(depth) >= beta
+        &&  eval - futility_margin(depth, improving) >= beta
         &&  eval < VALUE_KNOWN_WIN) // Do not return unproven wins
         return eval;
 
@@ -761,6 +764,7 @@ namespace {
         Value rbeta = std::min(beta + 200, VALUE_INFINITE);
         MovePicker mp(pos, ttMove, rbeta - ss->staticEval, &thisThread->captureHistory);
         int probCutCount = 0;
+
         while (  (move = mp.next_move()) != MOVE_NONE
                && probCutCount < depth / ONE_PLY - 3)
             if (pos.legal(move))
@@ -777,7 +781,7 @@ namespace {
                 // Perform a preliminary search at depth 1 to verify that the move holds.
                 // We will only do this search if the depth is not 5, thus avoiding two
                 // searches at depth 1 in a row.
-                if (depth > 5 * ONE_PLY)
+                if (depth != 5 * ONE_PLY)
                     value = -search<NonPV>(pos, ss+1, -rbeta, -rbeta+1, ONE_PLY, !cutNode, true);
 
                 // If the first search was skipped or was performed and held, perform