]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Templetize reduction() functions
[stockfish] / src / search.cpp
index 95aa76c4e14732ef2db6340a7fa26a28753777b1..145c7aa2a33a750b5f677868790df109bbc36a01 100644 (file)
@@ -52,7 +52,7 @@ using std::endl;
 namespace {
 
   /// Types
-
+  enum NodeType { NonPV, PV };
 
   // ThreadsManager class is used to handle all the threads related stuff in search,
   // init, starting, parking and, the most important, launching a slave thread at a
@@ -215,11 +215,10 @@ namespace {
   // Step 14. Reduced search
 
   // Reduction lookup tables (initialized at startup) and their getter functions
-  int8_t    PVReductionMatrix[64][64]; // [depth][moveNumber]
-  int8_t NonPVReductionMatrix[64][64]; // [depth][moveNumber]
+  int8_t ReductionMatrix[2][64][64]; // [pv][depth][moveNumber]
 
-  inline Depth    pv_reduction(Depth d, int mn) { return (Depth)    PVReductionMatrix[Min(d / 2, 63)][Min(mn, 63)]; }
-  inline Depth nonpv_reduction(Depth d, int mn) { return (Depth) NonPVReductionMatrix[Min(d / 2, 63)][Min(mn, 63)]; }
+  template <NodeType PV>
+  inline Depth reduction(Depth d, int mn) { return (Depth) ReductionMatrix[PV][Min(d / 2, 63)][Min(mn, 63)]; }
 
   // Common adjustments
 
@@ -280,7 +279,7 @@ namespace {
   Value id_loop(const Position& pos, Move searchMoves[]);
   Value root_search(Position& pos, SearchStack ss[], RootMoveList& rml, Value* alphaPtr, Value* betaPtr);
 
-  template <bool PvNode>
+  template <NodeType PvNode>
   Value search(Position& pos, SearchStack ss[], Value alpha, Value beta, Depth depth, int ply, bool allowNullmove, int threadID,  Move excludedMove = MOVE_NONE);
 
   Value qsearch(Position& pos, SearchStack ss[], Value alpha, Value beta, Depth depth, int ply, int threadID);
@@ -552,8 +551,8 @@ void init_search() {
       {
           double    pvRed = log(double(i)) * log(double(j)) / 3.0;
           double nonPVRed = log(double(i)) * log(double(j)) / 1.5;
-          PVReductionMatrix[i][j]    = (int8_t) (   pvRed >= 1.0 ? floor(   pvRed * int(OnePly)) : 0);
-          NonPVReductionMatrix[i][j] = (int8_t) (nonPVRed >= 1.0 ? floor(nonPVRed * int(OnePly)) : 0);
+          ReductionMatrix[PV][i][j]    = (int8_t) (   pvRed >= 1.0 ? floor(   pvRed * int(OnePly)) : 0);
+          ReductionMatrix[NonPV][i][j] = (int8_t) (nonPVRed >= 1.0 ? floor(nonPVRed * int(OnePly)) : 0);
       }
 
   // Init futility margins array
@@ -870,7 +869,7 @@ namespace {
                         alpha = -VALUE_INFINITE;
 
                     // Full depth PV search, done on first move or after a fail high
-                    value = -search<true>(pos, ss, -beta, -alpha, newDepth, 1, false, 0);
+                    value = -search<PV>(pos, ss, -beta, -alpha, newDepth, 1, false, 0);
                 }
                 else
                 {
@@ -883,11 +882,11 @@ namespace {
                         && !captureOrPromotion
                         && !move_is_castle(move))
                     {
-                        ss[0].reduction = pv_reduction(depth, i - MultiPV + 2);
+                        ss[0].reduction = reduction<PV>(depth, i - MultiPV + 2);
                         if (ss[0].reduction)
                         {
                             // Reduced depth non-pv search using alpha as upperbound
-                            value = -search<false>(pos, ss, -(alpha+1), -alpha, newDepth-ss[0].reduction, 1, true, 0);
+                            value = -search<NonPV>(pos, ss, -(alpha+1), -alpha, newDepth-ss[0].reduction, 1, true, 0);
                             doFullDepthSearch = (value > alpha);
                         }
                     }
@@ -897,12 +896,12 @@ namespace {
                     {
                         // Full depth non-pv search using alpha as upperbound
                         ss[0].reduction = Depth(0);
-                        value = -search<false>(pos, ss, -(alpha+1), -alpha, newDepth, 1, true, 0);
+                        value = -search<NonPV>(pos, ss, -(alpha+1), -alpha, newDepth, 1, true, 0);
 
                         // If we are above alpha then research at same depth but as PV
                         // to get a correct score or eventually a fail high above beta.
                         if (value > alpha)
-                            value = -search<true>(pos, ss, -beta, -alpha, newDepth, 1, false, 0);
+                            value = -search<PV>(pos, ss, -beta, -alpha, newDepth, 1, false, 0);
                     }
                 }
 
@@ -1024,11 +1023,10 @@ namespace {
 
   // search_pv() is the main search function for PV nodes.
 
-  template <bool PvNode>
+  template <NodeType PvNode>
   Value search(Position& pos, SearchStack ss[], Value alpha, Value beta,
                Depth depth, int ply, bool allowNullmove, int threadID, Move excludedMove) {
 
-
     assert(alpha >= -VALUE_INFINITE && alpha <= VALUE_INFINITE);
     assert(beta > alpha && beta <= VALUE_INFINITE);
     assert(ply >= 0 && ply < PLY_MAX);
@@ -1161,7 +1159,7 @@ namespace {
 
         pos.do_null_move(st);
 
-        nullValue = -search<false>(pos, ss, -beta, -alpha, depth-R*OnePly, ply+1, false, threadID);
+        nullValue = -search<NonPV>(pos, ss, -beta, -alpha, depth-R*OnePly, ply+1, false, threadID);
 
         pos.undo_null_move();
 
@@ -1175,7 +1173,7 @@ namespace {
                 return nullValue;
 
             // Do zugzwang verification search
-            Value v = search<false>(pos, ss, alpha, beta, depth-5*OnePly, ply, false, threadID);
+            Value v = search<NonPV>(pos, ss, alpha, beta, depth-5*OnePly, ply, false, threadID);
             if (v >= beta)
                 return nullValue;
         } else {
@@ -1202,7 +1200,7 @@ namespace {
         && depth >= IIDDepthAtPVNodes
         && ttMove == MOVE_NONE)
     {
-        search<true>(pos, ss, alpha, beta, depth-2*OnePly, ply, false, threadID);
+        search<PV>(pos, ss, alpha, beta, depth-2*OnePly, ply, false, threadID);
         ttMove = ss[ply].pv[ply];
         tte = TT.retrieve(posKey);
     }
@@ -1213,7 +1211,7 @@ namespace {
         && !isCheck
         && ss[ply].eval >= beta - IIDMargin)
     {
-        search<false>(pos, ss, alpha, beta, depth/2, ply, false, threadID);
+        search<NonPV>(pos, ss, alpha, beta, depth/2, ply, false, threadID);
         ttMove = ss[ply].pv[ply];
         tte = TT.retrieve(posKey);
     }
@@ -1259,7 +1257,7 @@ namespace {
 
           if (abs(ttValue) < VALUE_KNOWN_WIN)
           {
-              Value excValue = search<false>(pos, ss, ttValue - SingularExtensionMargin - 1, ttValue - SingularExtensionMargin, depth / 2, ply, false, threadID, move);
+              Value excValue = search<NonPV>(pos, ss, ttValue - SingularExtensionMargin - 1, ttValue - SingularExtensionMargin, depth / 2, ply, false, threadID, move);
 
               if (excValue < ttValue - SingularExtensionMargin)
                   ext = OnePly;
@@ -1286,7 +1284,7 @@ namespace {
               continue;
 
           // Value based pruning
-          Depth predictedDepth = newDepth - nonpv_reduction(depth, moveCount); // We illogically ignore reduction condition depth >= 3*OnePly
+          Depth predictedDepth = newDepth - reduction<NonPV>(depth, moveCount); // We illogically ignore reduction condition depth >= 3*OnePly
           futilityValueScaled =  ss[ply].eval + futility_margin(predictedDepth, moveCount)
                                + H.gain(pos.piece_on(move_from(move)), move_to(move));
 
@@ -1304,7 +1302,7 @@ namespace {
       // Step extra. pv search (only in PV nodes)
       // The first move in list is the expected PV
       if (PvNode && moveCount == 1)
-          value = -search<true>(pos, ss, -beta, -alpha, newDepth, ply+1, false, threadID);
+          value = -search<PV>(pos, ss, -beta, -alpha, newDepth, ply+1, false, threadID);
       else
       {
         // Step 14. Reduced search
@@ -1317,10 +1315,10 @@ namespace {
             && !move_is_castle(move)
             && !move_is_killer(move, ss[ply]))
         {
-            ss[ply].reduction = (PvNode ? pv_reduction(depth, moveCount) : nonpv_reduction(depth, moveCount));
+            ss[ply].reduction = reduction<PvNode>(depth, moveCount);
             if (ss[ply].reduction)
             {
-                value = -search<false>(pos, ss, -(alpha+1), -alpha, newDepth-ss[ply].reduction, ply+1, true, threadID);
+                value = -search<NonPV>(pos, ss, -(alpha+1), -alpha, newDepth-ss[ply].reduction, ply+1, true, threadID);
                 doFullDepthSearch = (value > alpha);
             }
         }
@@ -1329,11 +1327,11 @@ namespace {
         if (doFullDepthSearch)
         {
             ss[ply].reduction = Depth(0);
-            value = -search<false>(pos, ss, -(alpha+1), -alpha, newDepth, ply+1, true, threadID);
+            value = -search<NonPV>(pos, ss, -(alpha+1), -alpha, newDepth, ply+1, true, threadID);
 
             // Step extra. pv search (only in PV nodes)
             if (PvNode && value > alpha && value < beta)
-                value = -search<true>(pos, ss, -beta, -alpha, newDepth, ply+1, false, threadID);
+                value = -search<PV>(pos, ss, -beta, -alpha, newDepth, ply+1, false, threadID);
         }
       }
 
@@ -1659,7 +1657,7 @@ namespace {
           }
 
           // Value based pruning
-          Depth predictedDepth = newDepth - nonpv_reduction(sp->depth, moveCount);
+          Depth predictedDepth = newDepth - reduction<NonPV>(sp->depth, moveCount);
           futilityValueScaled =  ss[sp->ply].eval + futility_margin(predictedDepth, moveCount)
                                + H.gain(pos.piece_on(move_from(move)), move_to(move));
 
@@ -1685,10 +1683,10 @@ namespace {
           && !move_is_castle(move)
           && !move_is_killer(move, ss[sp->ply]))
       {
-          ss[sp->ply].reduction = nonpv_reduction(sp->depth, moveCount);
+          ss[sp->ply].reduction = reduction<NonPV>(sp->depth, moveCount);
           if (ss[sp->ply].reduction)
           {
-              value = -search<false>(pos, ss, -(sp->alpha+1), -(sp->alpha), newDepth-ss[sp->ply].reduction, sp->ply+1, true, threadID);
+              value = -search<NonPV>(pos, ss, -(sp->alpha+1), -(sp->alpha), newDepth-ss[sp->ply].reduction, sp->ply+1, true, threadID);
               doFullDepthSearch = (value >= sp->beta && !TM.thread_should_stop(threadID));
           }
       }
@@ -1697,7 +1695,7 @@ namespace {
       if (doFullDepthSearch)
       {
           ss[sp->ply].reduction = Depth(0);
-          value = -search<false>(pos, ss, -(sp->alpha+1), -(sp->alpha), newDepth, sp->ply+1, true, threadID);
+          value = -search<NonPV>(pos, ss, -(sp->alpha+1), -(sp->alpha), newDepth, sp->ply+1, true, threadID);
       }
 
       // Step 16. Undo move
@@ -1790,11 +1788,11 @@ namespace {
           && !move_is_castle(move)
           && !move_is_killer(move, ss[sp->ply]))
       {
-          ss[sp->ply].reduction = pv_reduction(sp->depth, moveCount);
+          ss[sp->ply].reduction = reduction<PV>(sp->depth, moveCount);
           if (ss[sp->ply].reduction)
           {
               Value localAlpha = sp->alpha;
-              value = -search<false>(pos, ss, -(localAlpha+1), -localAlpha, newDepth-ss[sp->ply].reduction, sp->ply+1, true, threadID);
+              value = -search<NonPV>(pos, ss, -(localAlpha+1), -localAlpha, newDepth-ss[sp->ply].reduction, sp->ply+1, true, threadID);
               doFullDepthSearch = (value > localAlpha && !TM.thread_should_stop(threadID));
           }
       }
@@ -1804,7 +1802,7 @@ namespace {
       {
           Value localAlpha = sp->alpha;
           ss[sp->ply].reduction = Depth(0);
-          value = -search<false>(pos, ss, -(localAlpha+1), -localAlpha, newDepth, sp->ply+1, true, threadID);
+          value = -search<NonPV>(pos, ss, -(localAlpha+1), -localAlpha, newDepth, sp->ply+1, true, threadID);
 
           if (value > localAlpha && value < sp->beta && !TM.thread_should_stop(threadID))
           {
@@ -1812,7 +1810,7 @@ namespace {
               // to be higher or equal then beta, if so, avoid to start a PV search.
               localAlpha = sp->alpha;
               if (localAlpha < sp->beta)
-                  value = -search<true>(pos, ss, -sp->beta, -localAlpha, newDepth, sp->ply+1, false, threadID);
+                  value = -search<PV>(pos, ss, -sp->beta, -localAlpha, newDepth, sp->ply+1, false, threadID);
           }
       }