]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Fix moveCount after legality check delay
[stockfish] / src / search.cpp
index dcfb7d46aff3177d95fba2c1cfdc7e13f6ea922e..dc6ad98b10a937d07997f52f8cf5faed61e8914a 100644 (file)
@@ -681,7 +681,7 @@ namespace {
     ValueType vt;
     Value bestValue, value, oldAlpha;
     Value refinedValue, nullValue, futilityBase, futilityValueScaled; // Non-PV specific
-    bool isPvMove, inCheck, singularExtensionNode, givesCheck, captureOrPromotion, dangerous, isBadCap;
+    bool isPvMove, inCheck, singularExtensionNode, givesCheck, captureOrPromotion, dangerous;
     int moveCount = 0, playedMoveCount = 0;
     int threadID = pos.thread();
     SplitPoint* sp = NULL;
@@ -880,6 +880,7 @@ split_point_start: // At split points actual search starts from here
     // Initialize a MovePicker object for the current position
     MovePickerExt<SpNode, Root> mp(pos, ttMove, depth, H, ss, (PvNode ? -VALUE_INFINITE : beta));
     CheckInfo ci(pos);
+    Bitboard pinned = pos.pinned_pieces(pos.side_to_move());
     ss->bestMove = MOVE_NONE;
     futilityBase = ss->eval + ss->evalMargin;
     singularExtensionNode =   !Root
@@ -903,13 +904,18 @@ split_point_start: // At split points actual search starts from here
     {
       assert(move_is_ok(move));
 
+      if (move == excludedMove)
+          continue;
+
+      // At PV and SpNode nodes we want the moves to be legal
+      if ((PvNode || SpNode) && !pos.pl_move_is_legal(move, pinned))
+          continue;
+
       if (SpNode)
       {
           moveCount = ++sp->moveCount;
           lock_release(&(sp->lock));
       }
-      else if (move == excludedMove)
-          continue;
       else
           moveCount++;
 
@@ -949,6 +955,7 @@ split_point_start: // At split points actual search starts from here
       // a margin then we extend ttMove.
       if (   singularExtensionNode
           && move == ttMove
+          && pos.pl_move_is_legal(move, pinned)
           && ext < ONE_PLY)
       {
           Value ttValue = value_from_tt(tte->value(), ss->ply);
@@ -968,7 +975,6 @@ split_point_start: // At split points actual search starts from here
       }
 
       // Update current move (this must be done after singular extension search)
-      ss->currentMove = move;
       newDepth = depth - ONE_PLY + ext;
 
       // Step 12. Futility pruning (is omitted in PV nodes)
@@ -1023,15 +1029,14 @@ split_point_start: // At split points actual search starts from here
           }
       }
 
-      // Bad capture detection. Will be used by prob-cut search
-      isBadCap =   depth >= 3 * ONE_PLY
-                && depth < 8 * ONE_PLY
-                && captureOrPromotion
-                && move != ttMove
-                && !dangerous
-                && !move_is_promotion(move)
-                &&  abs(alpha) < VALUE_MATE_IN_PLY_MAX
-                &&  pos.see_sign(move) < 0;
+      // Check for legality only before to do the move
+      if (!pos.pl_move_is_legal(move, pinned))
+      {
+          moveCount--;
+          continue;
+      }
+
+      ss->currentMove = move;
 
       // Step 13. Make the move
       pos.do_move(move, st, ci, givesCheck);
@@ -1076,7 +1081,13 @@ split_point_start: // At split points actual search starts from here
 
           // Probcut search for bad captures. If a reduced search returns a value
           // very below beta then we can (almost) safely prune the bad capture.
-          if (isBadCap)
+          if (   depth >= 3 * ONE_PLY
+              && depth < 8 * ONE_PLY
+              && mp.isBadCapture()
+              && move != ttMove
+              && !dangerous
+              && !move_is_promotion(move)
+              &&  abs(alpha) < VALUE_MATE_IN_PLY_MAX)
           {
               ss->reduction = 3 * ONE_PLY;
               Value rAlpha = alpha - 300;
@@ -1329,6 +1340,7 @@ split_point_start: // At split points actual search starts from here
     // be generated.
     MovePicker mp(pos, ttMove, depth, H);
     CheckInfo ci(pos);
+    Bitboard pinned = pos.pinned_pieces(pos.side_to_move());
 
     // Loop through the moves until no moves remain or a beta cutoff occurs
     while (   alpha < beta
@@ -1366,7 +1378,8 @@ split_point_start: // At split points actual search starts from here
       }
 
       // Detect non-capture evasions that are candidate to be pruned
-      evasionPrunable =   inCheck
+      evasionPrunable =   !PvNode
+                       && inCheck
                        && bestValue > VALUE_MATED_IN_PLY_MAX
                        && !pos.move_is_capture(move)
                        && !pos.can_castle(pos.side_to_move());
@@ -1395,6 +1408,10 @@ split_point_start: // At split points actual search starts from here
           continue;
       }
 
+      // Check for legality only before to do the move
+      if (!pos.pl_move_is_legal(move, pinned))
+          continue;
+
       // Update current move
       ss->currentMove = move;
 
@@ -1983,13 +2000,14 @@ split_point_start: // At split points actual search starts from here
     TTEntry* tte;
     int ply = 1;
 
-    assert(pv[0] != MOVE_NONE && pos.move_is_legal(pv[0]));
+    assert(pv[0] != MOVE_NONE && pos.move_is_pl(pv[0]));
 
     pos.do_move(pv[0], *st++);
 
     while (   (tte = TT.probe(pos.get_key())) != NULL
            && tte->move() != MOVE_NONE
-           && pos.move_is_legal(tte->move())
+           && pos.move_is_pl(tte->move())
+           && pos.pl_move_is_legal(tte->move(), pos.pinned_pieces(pos.side_to_move()))
            && ply < PLY_MAX
            && (!pos.is_draw() || ply < 2))
     {
@@ -2013,7 +2031,7 @@ split_point_start: // At split points actual search starts from here
     Value v, m = VALUE_NONE;
     int ply = 0;
 
-    assert(pv[0] != MOVE_NONE && pos.move_is_legal(pv[0]));
+    assert(pv[0] != MOVE_NONE && pos.move_is_pl(pv[0]));
 
     do {
         k = pos.get_key();