]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Introduce and use qsearch_scoring()
[stockfish] / src / search.cpp
index 6d75cc3de34b7ee44021fd6b78b330791a8fb807..3f482e77146490cad1fc57e4ca06fd5efec64726 100644 (file)
@@ -233,11 +233,6 @@ namespace {
   template <NodeType PV>
   inline Depth reduction(Depth d, int mn) { return (Depth) ReductionMatrix[PV][Min(d / 2, 63)][Min(mn, 63)]; }
 
-  // Common adjustments
-
-  // Search depth at iteration 1
-  const Depth InitialDepth = ONE_PLY;
-
   // Easy move margin. An easy move candidate must be at least this much
   // better than the second best move.
   const Value EasyMoveMargin = Value(0x200);
@@ -307,6 +302,7 @@ namespace {
   void update_history(const Position& pos, Move move, Depth depth, Move movesSearched[], int moveCount);
   void update_killers(Move m, Move killers[]);
   void update_gains(const Position& pos, Move move, Value before, Value after);
+  void qsearch_scoring(Position& pos, MoveStack* mlist, MoveStack* last);
 
   int current_search_time();
   std::string value_to_uci(Value v);
@@ -329,8 +325,8 @@ namespace {
   // before to search them.
   template<> struct MovePickerExt<false, true> : public MovePicker {
 
-    MovePickerExt(const Position& p, Move, Depth d, const History& h, SearchStack* ss, Value b)
-                 : MovePicker(p, Rml[0].pv[0], d, h, ss, b), firstCall(true) {
+    MovePickerExt(const Position& p, Move ttm, Depth d, const History& h, SearchStack* ss, Value b)
+                 : MovePicker(p, ttm, d, h, ss, b), firstCall(true) {
       Move move;
       Value score = VALUE_ZERO;
 
@@ -656,7 +652,7 @@ namespace {
         cout << "info depth " << iteration << endl;
 
         Rml.bestMoveChanges = researchCountFL = researchCountFH = 0;
-        depth = (iteration - 2) * ONE_PLY + InitialDepth;
+        depth = (iteration - 1) * ONE_PLY;
 
         // Calculate dynamic aspiration window based on previous iterations
         if (MultiPV == 1 && iteration >= 6 && abs(bestValues[iteration - 1]) < VALUE_KNOWN_WIN)
@@ -793,7 +789,7 @@ namespace {
     Value refinedValue, nullValue, futilityBase, futilityValueScaled; // Non-PV specific
     bool isPvMove, isCheck, singleEvasion, singularExtensionNode, moveIsCheck, captureOrPromotion, dangerous;
     bool mateThreat = false;
-    int moveCount = 0;
+    int moveCount = 0, playedMoveCount = 0;
     int threadID = pos.thread();
     SplitPoint* sp = NULL;
 
@@ -1027,7 +1023,7 @@ split_point_start: // At split points actual search starts from here
       else if (move == excludedMove)
           continue;
       else
-          movesSearched[moveCount++] = move;
+          moveCount++;
 
       if (Root)
       {
@@ -1142,6 +1138,9 @@ split_point_start: // At split points actual search starts from here
       // Step 13. Make the move
       pos.do_move(move, st, ci, moveIsCheck);
 
+      if (!SpNode && !captureOrPromotion)
+          movesSearched[playedMoveCount++] = move;
+
       // Step extra. pv search (only in PV nodes)
       // The first move in list is the expected PV
       if (isPvMove)
@@ -1321,7 +1320,7 @@ split_point_start: // At split points actual search starts from here
         if (    bestValue >= beta
             && !pos.move_is_capture_or_promotion(move))
         {
-            update_history(pos, move, depth, movesSearched, moveCount);
+            update_history(pos, move, depth, movesSearched, playedMoveCount);
             update_killers(move, ss->killers);
         }
     }
@@ -1524,6 +1523,26 @@ split_point_start: // At split points actual search starts from here
   }
 
 
+  // qsearch_scoring() scores each move of a list using a qsearch() evaluation,
+  // it is used in RootMoveList to get an initial scoring.
+  void qsearch_scoring(Position& pos, MoveStack* mlist, MoveStack* last) {
+
+    SearchStack ss[PLY_MAX_PLUS_2];
+    StateInfo st;
+
+    memset(ss, 0, 4 * sizeof(SearchStack));
+    ss[0].eval = ss[0].evalMargin = VALUE_NONE;
+
+    for (MoveStack* cur = mlist; cur != last; cur++)
+    {
+        ss[0].currentMove = cur->move;
+        pos.do_move(cur->move, st);
+        cur->score = -qsearch<PV>(pos, ss+1, -VALUE_INFINITE, VALUE_INFINITE, DEPTH_ZERO, 1);
+        pos.undo_move(cur->move);
+    }
+  }
+
+
   // check_is_dangerous() tests if a checking move can be pruned in qsearch().
   // bestValue is updated only when returning false because in that case move
   // will be pruned.
@@ -1833,8 +1852,7 @@ split_point_start: // At split points actual search starts from here
 
         assert(m != move);
 
-        if (!pos.move_is_capture_or_promotion(m))
-            H.update(pos.piece_on(move_from(m)), move_to(m), -bonus);
+        H.update(pos.piece_on(move_from(m)), move_to(m), -bonus);
     }
   }
 
@@ -1844,11 +1862,11 @@ split_point_start: // At split points actual search starts from here
 
   void update_killers(Move m, Move killers[]) {
 
-    if (m == killers[0])
-        return;
-
-    killers[1] = killers[0];
-    killers[0] = m;
+    if (m != killers[0])
+    {
+        killers[1] = killers[0];
+        killers[0] = m;
+    }
   }
 
 
@@ -2562,19 +2580,15 @@ split_point_start: // At split points actual search starts from here
 
   void RootMoveList::init(Position& pos, Move searchMoves[]) {
 
-    SearchStack ss[PLY_MAX_PLUS_2];
     MoveStack mlist[MOVES_MAX];
-    StateInfo st;
     Move* sm;
 
-    // Initialize search stack
-    memset(ss, 0, PLY_MAX_PLUS_2 * sizeof(SearchStack));
-    ss[0].eval = ss[0].evalMargin = VALUE_NONE;
-    bestMoveChanges = 0;
     clear();
+    bestMoveChanges = 0;
 
-    // Generate all legal moves
+    // Generate all legal moves and score them
     MoveStack* last = generate<MV_LEGAL>(pos, mlist);
+    qsearch_scoring(pos, mlist, last);
 
     // Add each move to the RootMoveList's vector
     for (MoveStack* cur = mlist; cur != last; cur++)
@@ -2586,16 +2600,11 @@ split_point_start: // At split points actual search starts from here
         if (searchMoves[0] && *sm != cur->move)
             continue;
 
-        // Find a quick score for the move and add to the list
-        pos.do_move(cur->move, st);
-
         RootMove rm;
-        rm.pv[0] = ss[0].currentMove = cur->move;
+        rm.pv[0] = cur->move;
         rm.pv[1] = MOVE_NONE;
-        rm.pv_score = -qsearch<PV>(pos, ss+1, -VALUE_INFINITE, VALUE_INFINITE, DEPTH_ZERO, 1);
+        rm.pv_score = Value(cur->score);
         push_back(rm);
-
-        pos.undo_move(cur->move);
     }
     sort();
   }