]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Fix PV output in Chess960
[stockfish] / src / search.cpp
index e7933f762422af11fe541156e10206ec3562b2bc..c018cbe3c49b7283d3d64de2f5ce235c79b74864 100644 (file)
@@ -212,7 +212,7 @@ namespace {
   int current_search_time(int set = 0);
   std::string score_to_uci(Value v, Value alpha, Value beta);
   std::string speed_to_uci(int64_t nodes);
   int current_search_time(int set = 0);
   std::string score_to_uci(Value v, Value alpha, Value beta);
   std::string speed_to_uci(int64_t nodes);
-  std::string pv_to_uci(Move pv[], int pvNum);
+  std::string pv_to_uci(Move pv[], int pvNum, bool chess960);
   std::string depth_to_uci(Depth depth);
   void poll(const Position& pos);
   void wait_for_stop_or_ponderhit();
   std::string depth_to_uci(Depth depth);
   void poll(const Position& pos);
   void wait_for_stop_or_ponderhit();
@@ -589,7 +589,7 @@ namespace {
                          << depth_to_uci(depth * ONE_PLY)
                          << score_to_uci(Rml[i].pv_score, alpha, beta)
                          << speed_to_uci(pos.nodes_searched())
                          << depth_to_uci(depth * ONE_PLY)
                          << score_to_uci(Rml[i].pv_score, alpha, beta)
                          << speed_to_uci(pos.nodes_searched())
-                         << pv_to_uci(Rml[i].pv, i + 1) << endl;
+                         << pv_to_uci(Rml[i].pv, i + 1, pos.is_chess960()) << endl;
 
             // In case of failing high/low increase aspiration window and research,
             // otherwise exit the fail high/low loop.
 
             // In case of failing high/low increase aspiration window and research,
             // otherwise exit the fail high/low loop.
@@ -633,12 +633,6 @@ namespace {
         // Check for some early stop condition
         if (!StopRequest && Limits.useTimeManagement())
         {
         // Check for some early stop condition
         if (!StopRequest && Limits.useTimeManagement())
         {
-            // Stop search early when the last two iterations returned a mate score
-            if (   depth >= 5
-                && abs(bestValues[depth])     >= VALUE_MATE_IN_PLY_MAX
-                && abs(bestValues[depth - 1]) >= VALUE_MATE_IN_PLY_MAX)
-                StopRequest = true;
-
             // Stop search early if one move seems to be much better than the
             // others or if there is only a single legal move. Also in the latter
             // case we search up to some depth anyway to get a proper score.
             // Stop search early if one move seems to be much better than the
             // others or if there is only a single legal move. Also in the latter
             // case we search up to some depth anyway to get a proper score.
@@ -726,7 +720,7 @@ namespace {
     if (PvNode && thread.maxPly < ss->ply)
         thread.maxPly = ss->ply;
 
     if (PvNode && thread.maxPly < ss->ply)
         thread.maxPly = ss->ply;
 
-    // Step 1. Initialize node.
+    // Step 1. Initialize node and poll. Polling can abort search
     if (!SpNode)
     {
         ss->currentMove = ss->bestMove = threatMove = (ss+1)->excludedMove = MOVE_NONE;
     if (!SpNode)
     {
         ss->currentMove = ss->bestMove = threatMove = (ss+1)->excludedMove = MOVE_NONE;
@@ -742,6 +736,18 @@ namespace {
         goto split_point_start;
     }
 
         goto split_point_start;
     }
 
+    if (pos.thread() == 0 && ++NodesSincePoll > NodesBetweenPolls)
+    {
+        NodesSincePoll = 0;
+        poll(pos);
+    }
+
+    // Step 2. Check for aborted search and immediate draw
+    if ((   StopRequest
+         || pos.is_draw<false>()
+         || ss->ply > PLY_MAX) && !RootNode)
+        return VALUE_DRAW;
+
     // Step 3. Mate distance pruning
     if (!RootNode)
     {
     // Step 3. Mate distance pruning
     if (!RootNode)
     {
@@ -902,12 +908,7 @@ namespace {
             if (pos.pl_move_is_legal(move, ci.pinned))
             {
                 pos.do_move(move, st, ci, pos.move_gives_check(move, ci));
             if (pos.pl_move_is_legal(move, ci.pinned))
             {
                 pos.do_move(move, st, ci, pos.move_gives_check(move, ci));
-
-                if (pos.is_draw<false>() || ss->ply + 1 > PLY_MAX)
-                    value = VALUE_DRAW;
-                else
-                    value = -search<NonPV>(pos, ss+1, -rbeta, -rbeta+1, rdepth);
-
+                value = -search<NonPV>(pos, ss+1, -rbeta, -rbeta+1, rdepth);
                 pos.undo_move(move);
                 if (value >= rbeta)
                     return value;
                 pos.undo_move(move);
                 if (value >= rbeta)
                     return value;
@@ -1097,22 +1098,6 @@ split_point_start: // At split points actual search starts from here
       // Step 14. Make the move
       pos.do_move(move, st, ci, givesCheck);
 
       // Step 14. Make the move
       pos.do_move(move, st, ci, givesCheck);
 
-      // Step XX. Poll. Check if search should be aborted.
-      if (pos.thread() == 0 && ++NodesSincePoll > NodesBetweenPolls)
-      {
-          NodesSincePoll = 0;
-          poll(pos);
-      }
-
-      // Step XX. Check for aborted search and immediate draw
-      if (   StopRequest
-          || pos.is_draw<false>()
-          || ss->ply + 1 > PLY_MAX)
-      {
-          value = VALUE_DRAW;
-          goto undo;
-      }
-
       // Step extra. pv search (only in PV nodes)
       // The first move in list is the expected PV
       if (isPvMove)
       // Step extra. pv search (only in PV nodes)
       // The first move in list is the expected PV
       if (isPvMove)
@@ -1159,7 +1144,6 @@ split_point_start: // At split points actual search starts from here
       }
 
       // Step 17. Undo move
       }
 
       // Step 17. Undo move
-undo:
       pos.undo_move(move);
 
       assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
       pos.undo_move(move);
 
       assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
@@ -1322,6 +1306,10 @@ undo:
     ss->bestMove = ss->currentMove = MOVE_NONE;
     ss->ply = (ss-1)->ply + 1;
 
     ss->bestMove = ss->currentMove = MOVE_NONE;
     ss->ply = (ss-1)->ply + 1;
 
+    // Check for an instant draw or maximum ply reached
+    if (pos.is_draw<true>() || ss->ply > PLY_MAX)
+        return VALUE_DRAW;
+
     // Decide whether or not to include checks, this fixes also the type of
     // TT entry depth that we are going to use. Note that in qsearch we use
     // only two types of depth in TT: DEPTH_QS_CHECKS or DEPTH_QS_NO_CHECKS.
     // Decide whether or not to include checks, this fixes also the type of
     // TT entry depth that we are going to use. Note that in qsearch we use
     // only two types of depth in TT: DEPTH_QS_CHECKS or DEPTH_QS_NO_CHECKS.
@@ -1456,12 +1444,7 @@ undo:
 
       // Make and search the move
       pos.do_move(move, st, ci, givesCheck);
 
       // Make and search the move
       pos.do_move(move, st, ci, givesCheck);
-
-      if (pos.is_draw<true>() || ss->ply+1 > PLY_MAX)
-          value = VALUE_DRAW;
-      else
-          value = -qsearch<NT>(pos, ss+1, -beta, -alpha, depth-ONE_PLY);
-
+      value = -qsearch<NT>(pos, ss+1, -beta, -alpha, depth-ONE_PLY);
       pos.undo_move(move);
 
       assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
       pos.undo_move(move);
 
       assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
@@ -1795,11 +1778,11 @@ undo:
   // pv_to_uci() returns a string with information on the current PV line
   // formatted according to UCI specification.
 
   // pv_to_uci() returns a string with information on the current PV line
   // formatted according to UCI specification.
 
-  std::string pv_to_uci(Move pv[], int pvNum) {
+  std::string pv_to_uci(Move pv[], int pvNum, bool chess960) {
 
     std::stringstream s;
 
 
     std::stringstream s;
 
-    s << " multipv " << pvNum << " pv ";
+    s << " multipv " << pvNum << " pv " << set960(chess960);
 
     for ( ; *pv != MOVE_NONE; pv++)
         s << *pv << " ";
 
     for ( ; *pv != MOVE_NONE; pv++)
         s << *pv << " ";