]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Expose new futility margin interface to UCI
[stockfish] / src / search.cpp
index a4ce7eff3abf10c7a76c057c75271a4f1a4949df..ffd484266b2196d0167c93b377c59b7a15230814 100644 (file)
@@ -162,11 +162,11 @@ namespace {
   bool UseQSearchFutilityPruning = true;
   bool UseFutilityPruning = true;
 
-  // Margins for futility pruning in the quiescence search, at frontier
-  // nodes, and at pre-frontier nodes
-  Value FutilityMargin0 = Value(0x80);
-  Value FutilityMargin1 = Value(0x100);
-  Value FutilityMargin2 = Value(0x200);
+  // Margins for futility pruning in the quiescence search, and at frontier
+  // and near frontier nodes
+  Value FutilityMarginQS = Value(0x80);
+  Value FutilityMargins[6] = { Value(0x120), Value(0x220), Value(0x250),
+                               Value(0x280), Value(0x320), Value(0x360) };
 
   // Razoring
   Depth RazorDepth = 4*OnePly;
@@ -415,9 +415,10 @@ void think(const Position &pos, bool infinite, bool ponder, int side_to_move,
   UseQSearchFutilityPruning = get_option_value_bool("Futility Pruning (Quiescence Search)");
   UseFutilityPruning = get_option_value_bool("Futility Pruning (Main Search)");
 
-  FutilityMargin0 = value_from_centipawns(get_option_value_int("Futility Margin 0"));
-  FutilityMargin1 = value_from_centipawns(get_option_value_int("Futility Margin 1"));
-  FutilityMargin2 = value_from_centipawns(get_option_value_int("Futility Margin 2"));
+  FutilityMarginQS = value_from_centipawns(get_option_value_int("Futility Margin (Quiescence Search)"));
+  int fmScale = get_option_value_int("Futility Margin (Main Serach)");
+  for (int i = 0; i < 6; i++)
+      FutilityMargins[i] = (FutilityMargins[i] * fmScale) / 100;
 
   RazorDepth = (get_option_value_int("Maximum Razoring Depth") + 1) * OnePly;
   RazorMargin = value_from_centipawns(get_option_value_int("Razoring Margin"));
@@ -1239,10 +1240,13 @@ namespace {
     // Null move search not allowed, try razoring
     else if (   !value_is_mate(beta)
              && approximateEval < beta - RazorMargin
-             && depth < RazorDepth)
+             && depth < RazorDepth
+             && depth > OnePly
+             && ttMove == MOVE_NONE
+             && !pos.has_pawn_on_7th(pos.side_to_move()))
     {
         Value v = qsearch(pos, ss, beta-1, beta, Depth(0), ply, threadID);
-        if (v < beta - RazorMargin / 2)
+        if (v < beta - RazorMargin / 2 - int(depth - OnePly) * RazorMargin / 8)
             return v;
     }
 
@@ -1314,12 +1318,13 @@ namespace {
               continue;
 
           // Value based pruning
-          if (depth < 6 * OnePly && approximateEval < beta)
+          if (depth < 7 * OnePly && approximateEval < beta)
           {
               if (futilityValue == VALUE_NONE)
                   futilityValue =  evaluate(pos, ei, threadID)
-                                + (depth < 2 * OnePly ? FutilityMargin1
-                                                      : FutilityMargin2 + (depth - 2*OnePly) * 32);
+                                 + FutilityMargins[int(depth)/2 - 1]
+                                 + 32 * (depth & 1);
+
               if (futilityValue < beta)
               {
                   if (futilityValue > bestValue)
@@ -1489,7 +1494,7 @@ namespace {
                               + Max(pos.midgame_value_of_piece_on(move_to(move)),
                                     pos.endgame_value_of_piece_on(move_to(move)))
                               + (move_is_ep(move) ? PawnValueEndgame : Value(0))
-                              + FutilityMargin0
+                              + FutilityMarginQS
                               + ei.futilityMargin;
 
           if (futilityValue < alpha)