]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Move legal check out of MovePicker
[stockfish] / src / search.cpp
index 0fbdab56722b41c8368ad0123dbe3b25c525d764..94eb6155bf756bfc8f938b43cbd038947bd9ff75 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
@@ -908,7 +909,7 @@ split_point_start: // At split points actual search starts from here
           moveCount = ++sp->moveCount;
           lock_release(&(sp->lock));
       }
-      else if (move == excludedMove)
+      else if (move == excludedMove || !pos.pl_move_is_legal(move, pinned))
           continue;
       else
           moveCount++;
@@ -937,7 +938,7 @@ split_point_start: // At split points actual search starts from here
       // At Root and at first iteration do a PV search on all the moves to score root moves
       isPvMove = (PvNode && moveCount <= (Root ? depth <= ONE_PLY ? 1000 : MultiPV : 1));
       givesCheck = pos.move_gives_check(move, ci);
-      captureOrPromotion = pos.move_is_capture_or_promotion(move);
+      captureOrPromotion = pos.move_is_capture(move) || move_is_promotion(move);
 
       // Step 11. Decide the new search depth
       ext = extension<PvNode>(pos, move, captureOrPromotion, givesCheck, &dangerous);
@@ -1023,16 +1024,6 @@ 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;
-
       // Step 13. Make the move
       pos.do_move(move, st, ci, givesCheck);
 
@@ -1076,7 +1067,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;
@@ -1215,7 +1212,8 @@ split_point_start: // At split points actual search starts from here
 
         // Update killers and history only for non capture moves that fails high
         if (    bestValue >= beta
-            && !pos.move_is_capture_or_promotion(move))
+            && !pos.move_is_capture(move)
+            && !move_is_promotion(move))
         {
             if (move != ss->killers[0])
             {
@@ -1328,6 +1326,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
@@ -1335,6 +1334,9 @@ split_point_start: // At split points actual search starts from here
     {
       assert(move_is_ok(move));
 
+      if (!pos.pl_move_is_legal(move, pinned))
+          continue;
+
       givesCheck = pos.move_gives_check(move, ci);
 
       // Futility pruning
@@ -1383,7 +1385,8 @@ split_point_start: // At split points actual search starts from here
           && !inCheck
           &&  givesCheck
           &&  move != ttMove
-          && !pos.move_is_capture_or_promotion(move)
+          && !pos.move_is_capture(move)
+          && !move_is_promotion(move)
           &&  ss->eval + PawnValueMidgame / 4 < beta
           && !check_is_dangerous(pos, move, futilityBase, beta, &bestValue))
       {
@@ -1626,7 +1629,7 @@ split_point_start: // At split points actual search starts from here
     assert(move_is_ok(m));
     assert(threat && move_is_ok(threat));
     assert(!pos.move_gives_check(m));
-    assert(!pos.move_is_capture_or_promotion(m));
+    assert(!pos.move_is_capture(m) && !move_is_promotion(m));
     assert(!pos.move_is_passed_pawn_push(m));
 
     Square mfrom, mto, tfrom, tto;
@@ -1981,13 +1984,16 @@ 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++);
 
+    Bitboard pinned = pos.pinned_pieces(pos.side_to_move());
+
     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(), pinned)
            && ply < PLY_MAX
            && (!pos.is_draw() || ply < 2))
     {
@@ -2011,7 +2017,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();