]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Convert also undo_null_move() to avoid passing UndoInfo object
[stockfish] / src / search.cpp
index 054ef45d5d05858ad1c6e97c624dcc224edb5241..8c847714150b7d74668f73a1ef2833f29c311b03 100644 (file)
@@ -133,9 +133,6 @@ namespace {
   // when the static evaluation is at most IIDMargin below beta.
   const Value IIDMargin = Value(0x100);
 
-  // Use easy moves?
-  const bool UseEasyMove = true;
-
   // Easy move margin.  An easy move candidate must be at least this much
   // better than the second best move.
   const Value EasyMoveMargin = Value(0x200);
@@ -165,13 +162,14 @@ namespace {
   bool UseQSearchFutilityPruning = true;
   bool UseFutilityPruning = true;
 
-  // Margins for futility pruning in the quiescence search, at frontier
-  // nodes, and at pre-frontier nodes
-  Value FutilityMargin0 = Value(0x80);
-  Value FutilityMargin1 = Value(0x100);
-  Value FutilityMargin2 = Value(0x300);
+  // Margins for futility pruning in the quiescence search, and at frontier
+  // and near frontier nodes
+  Value FutilityMarginQS = Value(0x80);
+  Value FutilityMargins[6] = { Value(0x100), Value(0x200), Value(0x250),
+                               Value(0x2A0), Value(0x340), Value(0x3A0) };
 
   // Razoring
+  const bool RazorAtDepthOne = false;
   Depth RazorDepth = 4*OnePly;
   Value RazorMargin = Value(0x300);
 
@@ -269,7 +267,7 @@ namespace {
   bool connected_moves(const Position &pos, Move m1, Move m2);
   bool value_is_mate(Value value);
   bool move_is_killer(Move m, const SearchStack& ss);
-  Depth extension(const Position &pos, Move m, bool pvNode, bool check, bool singleReply, bool mateThreat, bool* dangerous);
+  Depth extension(const Position &pos, Move m, bool pvNode, bool capture, bool check, bool singleReply, bool mateThreat, bool* dangerous);
   bool ok_to_do_nullmove(const Position &pos);
   bool ok_to_prune(const Position &pos, Move m, Move threat, Depth d);
   bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply);
@@ -293,8 +291,7 @@ namespace {
   bool idle_thread_exists(int master);
   bool split(const Position &pos, SearchStack *ss, int ply,
              Value *alpha, Value *beta, Value *bestValue, Depth depth,
-             int *moves, MovePicker *mp, Bitboard dcCandidates, int master,
-             bool pvNode);
+             int *moves, MovePicker *mp, int master, bool pvNode);
   void wake_sleeping_threads();
 
 #if !defined(_MSC_VER)
@@ -418,9 +415,10 @@ void think(const Position &pos, bool infinite, bool ponder, int side_to_move,
   UseQSearchFutilityPruning = get_option_value_bool("Futility Pruning (Quiescence Search)");
   UseFutilityPruning = get_option_value_bool("Futility Pruning (Main Search)");
 
-  FutilityMargin0 = value_from_centipawns(get_option_value_int("Futility Margin 0"));
-  FutilityMargin1 = value_from_centipawns(get_option_value_int("Futility Margin 1"));
-  FutilityMargin2 = value_from_centipawns(get_option_value_int("Futility Margin 2"));
+  FutilityMarginQS = value_from_centipawns(get_option_value_int("Futility Margin (Quiescence Search)"));
+  int fmScale = get_option_value_int("Futility Margin Scale Factor (Main Search)");
+  for (int i = 0; i < 6; i++)
+      FutilityMargins[i] = (FutilityMargins[i] * fmScale) / 100;
 
   RazorDepth = (get_option_value_int("Maximum Razoring Depth") + 1) * OnePly;
   RazorMargin = value_from_centipawns(get_option_value_int("Razoring Margin"));
@@ -450,7 +448,6 @@ void think(const Position &pos, bool infinite, bool ponder, int side_to_move,
   // Set thinking time:
   int myTime = time[side_to_move];
   int myIncrement = increment[side_to_move];
-  int oppTime = time[1 - side_to_move];
 
   if (!movesToGo) // Sudden death time control
   {
@@ -778,7 +775,6 @@ namespace {
 
     Value alpha = -VALUE_INFINITE;
     Value beta = VALUE_INFINITE, value;
-    Bitboard dcCandidates = pos.discovered_check_candidates(pos.side_to_move());
 
     // Loop through all the moves in the root move list
     for (int i = 0; i <  rml.move_count() && !AbortSearch; i++)
@@ -807,11 +803,11 @@ namespace {
 
         // Decide search depth for this move
         bool dangerous;
-        ext = extension(pos, move, true, pos.move_is_check(move), false, false, &dangerous);
+        ext = extension(pos, move, true, pos.move_is_capture(move), pos.move_is_check(move), false, false, &dangerous);
         newDepth = (Iteration - 2) * OnePly + ext + InitialDepth;
 
         // Make the move, and search it
-        pos.do_move(move, u, dcCandidates);
+        pos.do_move(move, u);
 
         if (i < MultiPV)
         {
@@ -839,7 +835,7 @@ namespace {
             }
         }
 
-        pos.undo_move(move, u);
+        pos.undo_move(move);
 
         // Finished searching the move. If AbortSearch is true, the search
         // was aborted because the user interrupted the search or because we
@@ -940,16 +936,17 @@ namespace {
     assert(ply >= 0 && ply < PLY_MAX);
     assert(threadID >= 0 && threadID < ActiveThreads);
 
-    // Initialize, and make an early exit in case of an aborted search,
-    // an instant draw, maximum ply reached, etc.
-    if (AbortSearch || thread_should_stop(threadID))
-        return Value(0);
-
     if (depth < OnePly)
         return qsearch(pos, ss, alpha, beta, Depth(0), ply, threadID);
 
+    // Initialize, and make an early exit in case of an aborted search,
+    // an instant draw, maximum ply reached, etc.
     init_node(pos, ss, ply, threadID);
 
+    // After init_node() that calls poll()
+    if (AbortSearch || thread_should_stop(threadID))
+        return Value(0);
+
     if (pos.is_draw())
         return VALUE_DRAW;
 
@@ -984,9 +981,9 @@ namespace {
     Move move, movesSearched[256];
     int moveCount = 0;
     Value value, bestValue = -VALUE_INFINITE;
-    Bitboard dcCandidates = mp.discovered_check_candidates();
+    Color us = pos.side_to_move();
     bool isCheck = pos.is_check();
-    bool mateThreat = pos.has_mate_threat(opposite_color(pos.side_to_move()));
+    bool mateThreat = pos.has_mate_threat(opposite_color(us));
 
     // Loop through all legal moves until no moves remain or a beta cutoff
     // occurs.
@@ -997,7 +994,7 @@ namespace {
       assert(move_is_ok(move));
 
       bool singleReply = (isCheck && mp.number_of_moves() == 1);
-      bool moveIsCheck = pos.move_is_check(move, dcCandidates);
+      bool moveIsCheck = pos.move_is_check(move);
       bool moveIsCapture = pos.move_is_capture(move);
 
       movesSearched[moveCount++] = ss[ply].currentMove = move;
@@ -1010,12 +1007,12 @@ namespace {
 
       // Decide the new search depth
       bool dangerous;
-      Depth ext = extension(pos, move, true, moveIsCheck, singleReply, mateThreat, &dangerous);
+      Depth ext = extension(pos, move, true, moveIsCapture, moveIsCheck, singleReply, mateThreat, &dangerous);
       Depth newDepth = depth - OnePly + ext;
 
       // Make and search the move
       UndoInfo u;
-      pos.do_move(move, u, dcCandidates);
+      pos.do_move(move, u);
 
       if (moveCount == 1) // The first move in list is the PV
           value = -search_pv(pos, ss, -beta, -alpha, newDepth, ply+1, threadID);
@@ -1037,7 +1034,7 @@ namespace {
         else
             value = alpha + 1; // Just to trigger next condition
 
-        if (value > alpha) // Go with full depth pv search
+        if (value > alpha) // Go with full depth non-pv search
         {
             ss[ply].reduction = Depth(0);
             value = -search(pos, ss, -alpha, newDepth, ply+1, true, threadID);
@@ -1057,7 +1054,7 @@ namespace {
           }
         }
       }
-      pos.undo_move(move, u);
+      pos.undo_move(move);
 
       assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
 
@@ -1075,7 +1072,9 @@ namespace {
           // If we are at ply 1, and we are searching the first root move at
           // ply 0, set the 'Problem' variable if the score has dropped a lot
           // (from the computer's point of view) since the previous iteration:
-          if (Iteration >= 2 && -value <= ValueByIteration[Iteration-1] - ProblemMargin)
+          if (   ply == 1
+              && Iteration >= 2
+              && -value <= ValueByIteration[Iteration-1] - ProblemMargin)
               Problem = true;
       }
 
@@ -1088,7 +1087,7 @@ namespace {
           && !AbortSearch
           && !thread_should_stop(threadID)
           && split(pos, ss, ply, &alpha, &beta, &bestValue, depth,
-                   &moveCount, &mp, dcCandidates, threadID, true))
+                   &moveCount, &mp, threadID, true))
           break;
     }
 
@@ -1132,21 +1131,22 @@ namespace {
     assert(ply >= 0 && ply < PLY_MAX);
     assert(threadID >= 0 && threadID < ActiveThreads);
 
-    EvalInfo ei;
+    if (depth < OnePly)
+        return qsearch(pos, ss, beta-1, beta, Depth(0), ply, threadID);
 
     // Initialize, and make an early exit in case of an aborted search,
     // an instant draw, maximum ply reached, etc.
+    init_node(pos, ss, ply, threadID);
+
+    // After init_node() that calls poll()
     if (AbortSearch || thread_should_stop(threadID))
         return Value(0);
 
-    if (depth < OnePly)
-        return qsearch(pos, ss, beta-1, beta, Depth(0), ply, threadID);
-
-    init_node(pos, ss, ply, threadID);
-
     if (pos.is_draw())
         return VALUE_DRAW;
 
+    EvalInfo ei;
+
     if (ply >= PLY_MAX - 1)
         return evaluate(pos, ei, threadID);
 
@@ -1189,8 +1189,8 @@ namespace {
         Value nullValue = -search(pos, ss, -(beta-1), depth-R*OnePly, ply+1, false, threadID);
 
         // Check for a null capture artifact, if the value without the null capture
-        // is above beta then there is a good possibility that this is a cut-node.
-        // We will do an IID later to find a ttMove.
+        // is above beta then mark the node as a suspicious failed low. We will verify
+        // later if we are really under threat.
         if (   UseNullDrivenIID
             && nullValue < beta
             && depth > 6 * OnePly
@@ -1201,7 +1201,7 @@ namespace {
             && pos.see(ss[ply + 1].currentMove) + nullValue >= beta)
             nullDrivenIID = true;
 
-        pos.undo_null_move(u);
+        pos.undo_null_move();
 
         if (value_is_mate(nullValue))
         {
@@ -1238,10 +1238,15 @@ namespace {
     // Null move search not allowed, try razoring
     else if (   !value_is_mate(beta)
              && approximateEval < beta - RazorMargin
-             && depth < RazorDepth)
+             && depth < RazorDepth
+             && (RazorAtDepthOne || depth > OnePly)
+             && ttMove == MOVE_NONE
+             && !pos.has_pawn_on_7th(pos.side_to_move()))
     {
         Value v = qsearch(pos, ss, beta-1, beta, Depth(0), ply, threadID);
-        if (v < beta - RazorMargin / 2)
+        if (   (v < beta - RazorMargin - RazorMargin / 4)
+            || (depth < 3*OnePly && v < beta - RazorMargin)
+            || (depth < 2*OnePly && v < beta - RazorMargin / 2))
             return v;
     }
 
@@ -1256,7 +1261,9 @@ namespace {
     {
         // The null move failed low due to a suspicious capture. Perhaps we
         // are facing a null capture artifact due to the side to move change
-        // and this is a cut-node. So it's a good time to search for a ttMove.
+        // and this position should fail high. So do a normal search with a
+        // reduced depth to get a good ttMove to use in the following full
+        // depth search.
         Move tm = ss[ply].threatMove;
 
         assert(tm != MOVE_NONE);
@@ -1274,7 +1281,6 @@ namespace {
     Move move, movesSearched[256];
     int moveCount = 0;
     Value value, bestValue = -VALUE_INFINITE;
-    Bitboard dcCandidates = mp.discovered_check_candidates();
     Value futilityValue = VALUE_NONE;
     bool useFutilityPruning =   UseFutilityPruning
                              && depth < SelectiveDepth
@@ -1289,14 +1295,14 @@ namespace {
       assert(move_is_ok(move));
 
       bool singleReply = (isCheck && mp.number_of_moves() == 1);
-      bool moveIsCheck = pos.move_is_check(move, dcCandidates);
+      bool moveIsCheck = pos.move_is_check(move);
       bool moveIsCapture = pos.move_is_capture(move);
 
       movesSearched[moveCount++] = ss[ply].currentMove = move;
 
       // Decide the new search depth
       bool dangerous;
-      Depth ext = extension(pos, move, false, moveIsCheck, singleReply, mateThreat, &dangerous);
+      Depth ext = extension(pos, move, false, moveIsCapture, moveIsCheck, singleReply, mateThreat, &dangerous);
       Depth newDepth = depth - OnePly + ext;
 
       // Futility pruning
@@ -1305,17 +1311,18 @@ namespace {
           && !moveIsCapture
           && !move_promotion(move))
       {
-          // History pruning. See ok_to_prune() definition.
+          // History pruning. See ok_to_prune() definition
           if (   moveCount >= 2 + int(depth)
               && ok_to_prune(pos, move, ss[ply].threatMove, depth))
               continue;
 
-          // Value based pruning.
-          if (depth < 3 * OnePly && approximateEval < beta)
+          // Value based pruning
+          if (depth < 7 * OnePly && approximateEval < beta)
           {
               if (futilityValue == VALUE_NONE)
                   futilityValue =  evaluate(pos, ei, threadID)
-                                + (depth < 2 * OnePly ? FutilityMargin1 : FutilityMargin2);
+                                 + FutilityMargins[int(depth)/2 - 1]
+                                 + 32 * (depth & 1);
 
               if (futilityValue < beta)
               {
@@ -1328,7 +1335,7 @@ namespace {
 
       // Make and search the move
       UndoInfo u;
-      pos.do_move(move, u, dcCandidates);
+      pos.do_move(move, u);
 
       // Try to reduce non-pv search depth by one ply if move seems not problematic,
       // if the move fails high will be re-searched at full depth.
@@ -1351,7 +1358,7 @@ namespace {
           ss[ply].reduction = Depth(0);
           value = -search(pos, ss, -(beta-1), newDepth, ply+1, true, threadID);
       }
-      pos.undo_move(move, u);
+      pos.undo_move(move);
 
       assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
 
@@ -1375,7 +1382,7 @@ namespace {
           && !AbortSearch
           && !thread_should_stop(threadID)
           && split(pos, ss, ply, &beta, &beta, &bestValue, depth, &moveCount,
-                   &mp, dcCandidates, threadID, false))
+                   &mp, threadID, false))
         break;
     }
 
@@ -1419,15 +1426,14 @@ namespace {
     assert(ply >= 0 && ply < PLY_MAX);
     assert(threadID >= 0 && threadID < ActiveThreads);
 
-    EvalInfo ei;
-
     // Initialize, and make an early exit in case of an aborted search,
     // an instant draw, maximum ply reached, etc.
+    init_node(pos, ss, ply, threadID);
+
+    // After init_node() that calls poll()
     if (AbortSearch || thread_should_stop(threadID))
         return Value(0);
 
-    init_node(pos, ss, ply, threadID);
-
     if (pos.is_draw())
         return VALUE_DRAW;
 
@@ -1437,6 +1443,7 @@ namespace {
         return value_from_tt(tte->value(), ply);
 
     // Evaluate the position statically
+    EvalInfo ei;
     bool isCheck = pos.is_check();
     Value staticValue = (isCheck ? -VALUE_INFINITE : evaluate(pos, ei, threadID));
 
@@ -1460,8 +1467,8 @@ namespace {
     MovePicker mp = MovePicker(pos, pvNode, MOVE_NONE, EmptySearchStack, depth, isCheck ? NULL : &ei);
     Move move;
     int moveCount = 0;
-    Bitboard dcCandidates = mp.discovered_check_candidates();
-    bool enoughMaterial = pos.non_pawn_material(pos.side_to_move()) > RookValueMidgame;
+    Color us = pos.side_to_move();
+    bool enoughMaterial = pos.non_pawn_material(us) > RookValueMidgame;
 
     // Loop through the moves until no moves remain or a beta cutoff
     // occurs.
@@ -1479,14 +1486,14 @@ namespace {
           && !isCheck
           && !pvNode
           && !move_promotion(move)
-          && !pos.move_is_check(move, dcCandidates)
+          && !pos.move_is_check(move)
           && !pos.move_is_passed_pawn_push(move))
       {
           Value futilityValue = staticValue
                               + Max(pos.midgame_value_of_piece_on(move_to(move)),
                                     pos.endgame_value_of_piece_on(move_to(move)))
                               + (move_is_ep(move) ? PawnValueEndgame : Value(0))
-                              + FutilityMargin0
+                              + FutilityMarginQS
                               + ei.futilityMargin;
 
           if (futilityValue < alpha)
@@ -1507,9 +1514,9 @@ namespace {
 
       // Make and search the move.
       UndoInfo u;
-      pos.do_move(move, u, dcCandidates);
+      pos.do_move(move, u);
       Value value = -qsearch(pos, ss, -beta, -alpha, depth-OnePly, ply+1, threadID);
-      pos.undo_move(move, u);
+      pos.undo_move(move);
 
       assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
 
@@ -1574,7 +1581,7 @@ namespace {
     {
       assert(move_is_ok(move));
 
-      bool moveIsCheck = pos.move_is_check(move, sp->dcCandidates);
+      bool moveIsCheck = pos.move_is_check(move);
       bool moveIsCapture = pos.move_is_capture(move);
 
       lock_grab(&(sp->lock));
@@ -1585,7 +1592,7 @@ namespace {
 
       // Decide the new search depth.
       bool dangerous;
-      Depth ext = extension(pos, move, false, moveIsCheck, false, false, &dangerous);
+      Depth ext = extension(pos, move, false, moveIsCapture, moveIsCheck, false, false, &dangerous);
       Depth newDepth = sp->depth - OnePly + ext;
 
       // Prune?
@@ -1599,7 +1606,7 @@ namespace {
 
       // Make and search the move.
       UndoInfo u;
-      pos.do_move(move, u, sp->dcCandidates);
+      pos.do_move(move, u);
 
       // Try to reduce non-pv search depth by one ply if move seems not problematic,
       // if the move fails high will be re-searched at full depth.
@@ -1621,7 +1628,7 @@ namespace {
           ss[sp->ply].reduction = Depth(0);
           value = -search(pos, ss, -(sp->beta - 1), newDepth, sp->ply+1, true, threadID);
       }
-      pos.undo_move(move, u);
+      pos.undo_move(move);
 
       assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
 
@@ -1684,7 +1691,7 @@ namespace {
            && !thread_should_stop(threadID)
            && (move = sp->mp->get_next_move(sp->lock)) != MOVE_NONE)
     {
-      bool moveIsCheck = pos.move_is_check(move, sp->dcCandidates);
+      bool moveIsCheck = pos.move_is_check(move);
       bool moveIsCapture = pos.move_is_capture(move);
 
       assert(move_is_ok(move));
@@ -1703,12 +1710,12 @@ namespace {
 
       // Decide the new search depth.
       bool dangerous;
-      Depth ext = extension(pos, move, true, moveIsCheck, false, false, &dangerous);
+      Depth ext = extension(pos, move, true, moveIsCapture, moveIsCheck, false, false, &dangerous);
       Depth newDepth = sp->depth - OnePly + ext;
 
       // Make and search the move.
       UndoInfo u;
-      pos.do_move(move, u, sp->dcCandidates);
+      pos.do_move(move, u);
 
       // Try to reduce non-pv search depth by one ply if move seems not problematic,
       // if the move fails high will be re-searched at full depth.
@@ -1744,7 +1751,7 @@ namespace {
               Threads[threadID].failHighPly1 = false;
         }
       }
-      pos.undo_move(move, u);
+      pos.undo_move(move);
 
       assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
 
@@ -1774,8 +1781,10 @@ namespace {
         }
         // If we are at ply 1, and we are searching the first root move at
         // ply 0, set the 'Problem' variable if the score has dropped a lot
-        // (from the computer's point of view) since the previous iteration:
-        if (Iteration >= 2 && -value <= ValueByIteration[Iteration-1] - ProblemMargin)
+        // (from the computer's point of view) since the previous iteration.
+        if (   sp->ply == 1
+            && Iteration >= 2
+            && -value <= ValueByIteration[Iteration-1] - ProblemMargin)
             Problem = true;
       }
       lock_release(&(sp->lock));
@@ -1784,7 +1793,7 @@ namespace {
     lock_grab(&(sp->lock));
 
     // If this is the master thread and we have been asked to stop because of
-    // a beta cutoff higher up in the tree, stop all slave threads:
+    // a beta cutoff higher up in the tree, stop all slave threads.
     if (sp->master == threadID && thread_should_stop(threadID))
         for (int i = 0; i < ActiveThreads; i++)
             if (sp->slaves[i])
@@ -1875,7 +1884,7 @@ namespace {
             pos.do_move(moves[count].move, u);
             moves[count].score = -qsearch(pos, ss, -VALUE_INFINITE, VALUE_INFINITE,
                                           Depth(0), 1, 0);
-            pos.undo_move(moves[count].move, u);
+            pos.undo_move(moves[count].move);
             moves[count].pv[0] = moves[i].move;
             moves[count].pv[1] = MOVE_NONE; // FIXME
             count++;
@@ -2101,7 +2110,7 @@ namespace {
 
     // Case 4: The destination square for m2 is attacked by the moving piece
     // in m1:
-    if(pos.piece_attacks_square(t1, t2))
+    if(pos.piece_attacks_square(pos.piece_on(t1), t1, t2))
       return true;
 
     // Case 5: Discovered check, checking piece is the piece moved in m1:
@@ -2166,7 +2175,7 @@ namespace {
   // extended, as example because the corresponding UCI option is set to zero,
   // the move is marked as 'dangerous' so, at least, we avoid to prune it.
 
-  Depth extension(const Position &pos, Move m, bool pvNode, bool check,
+  Depth extension(const Position& pos, Move m, bool pvNode, bool capture, bool check,
                   bool singleReply, bool mateThreat, bool* dangerous) {
 
     assert(m != MOVE_NONE);
@@ -2183,18 +2192,21 @@ namespace {
     if (mateThreat)
         result += MateThreatExtension[pvNode];
 
-    if (pos.move_is_pawn_push_to_7th(m))
+    if (pos.type_of_piece_on(move_from(m)) == PAWN)
     {
-        result += PawnPushTo7thExtension[pvNode];
-        *dangerous = true;
-    }
-    if (pos.move_is_passed_pawn_push(m))
-    {
-        result += PassedPawnExtension[pvNode];
-        *dangerous = true;
+        if (pos.move_is_pawn_push_to_7th(m))
+        {
+            result += PawnPushTo7thExtension[pvNode];
+            *dangerous = true;
+        }
+        if (pos.move_is_passed_pawn_push(m))
+        {
+            result += PassedPawnExtension[pvNode];
+            *dangerous = true;
+        }
     }
 
-    if (   pos.move_is_capture(m)
+    if (   capture
         && pos.type_of_piece_on(move_to(m)) != PAWN
         && (  pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK)
             - pos.midgame_value_of_piece_on(move_to(m)) == Value(0))
@@ -2206,7 +2218,7 @@ namespace {
     }
 
     if (   pvNode
-        && pos.move_is_capture(m)
+        && capture
         && pos.type_of_piece_on(move_to(m)) != PAWN
         && pos.see(m) >= 0)
     {
@@ -2280,7 +2292,8 @@ namespace {
     if (  !PruneBlockingMoves
         && threat != MOVE_NONE
         && piece_is_slider(pos.piece_on(tfrom))
-        && bit_is_set(squares_between(tfrom, tto), mto) && pos.see(m) >= 0)
+        && bit_is_set(squares_between(tfrom, tto), mto)
+        && pos.see(m) >= 0)
             return false;
 
     return true;
@@ -2659,8 +2672,7 @@ namespace {
 
   bool split(const Position &p, SearchStack *sstck, int ply,
              Value *alpha, Value *beta, Value *bestValue,
-             Depth depth, int *moves,
-             MovePicker *mp, Bitboard dcCandidates, int master, bool pvNode) {
+             Depth depth, int *moves, MovePicker *mp, int master, bool pvNode) {
     assert(p.is_ok());
     assert(sstck != NULL);
     assert(ply >= 0 && ply < PLY_MAX);
@@ -2696,7 +2708,6 @@ namespace {
     splitPoint->alpha = pvNode? *alpha : (*beta - 1);
     splitPoint->beta = *beta;
     splitPoint->pvNode = pvNode;
-    splitPoint->dcCandidates = dcCandidates;
     splitPoint->bestValue = *bestValue;
     splitPoint->master = master;
     splitPoint->mp = mp;