]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Introduce and use MovePickerExt
[stockfish] / src / search.cpp
index 122679238958497d4f4700482e326e52fbb1a12f..502f12cf72cefa0ff75a38ada3be7f5e37a89787 100644 (file)
@@ -248,6 +248,9 @@ namespace {
   // Book object
   Book OpeningBook;
 
+  // Pointer to root move list
+  RootMoveList* Rml;
+
   // Iteration counter
   int Iteration;
 
@@ -286,9 +289,8 @@ namespace {
   /// Local functions
 
   Move id_loop(Position& pos, Move searchMoves[], Move* ponderMove);
-  Value root_search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, RootMoveList& rml);
 
-  template <NodeType PvNode, bool SpNode>
+  template <NodeType PvNode, bool SpNode, bool Root>
   Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply);
 
   template <NodeType PvNode>
@@ -298,7 +300,7 @@ namespace {
   inline Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply) {
 
       return depth < ONE_PLY ? qsearch<PvNode>(pos, ss, alpha, beta, DEPTH_ZERO, ply)
-                             : search<PvNode, false>(pos, ss, alpha, beta, depth, ply);
+                             : search<PvNode, false, false>(pos, ss, alpha, beta, depth, ply);
   }
 
   template <NodeType PvNode>
@@ -329,7 +331,54 @@ namespace {
   DWORD WINAPI init_thread(LPVOID threadID);
 #endif
 
-}
+
+  // A dispatcher to choose among different move sources according to the type of node
+  template<bool SpNode, bool Root> struct MovePickerExt;
+
+  // In Root nodes use RootMoveList Rml as source
+  template<> struct MovePickerExt<false, true> {
+
+      MovePickerExt(const Position&, Move, Depth, const History&, SearchStack*, Value)
+                  : rm(Rml->begin()), firstCall(true) {}
+
+      Move get_next_move() {
+
+        if (!firstCall)
+            ++rm;
+        else
+            firstCall = false;
+
+        return rm != Rml->end() ? rm->pv[0] : MOVE_NONE;
+      }
+      int number_of_evasions() const { return (int)Rml->size(); }
+
+      RootMoveList::iterator rm;
+      bool firstCall;
+  };
+
+  // In SpNodes use split point's shared MovePicker as move source
+  template<> struct MovePickerExt<true, false> {
+
+      MovePickerExt(const Position&, Move, Depth, const History&, SearchStack* ss, Value)
+                  : mp(ss->sp->mp) {}
+
+      Move get_next_move() { return mp->get_next_move(); }
+      int number_of_evasions() const { return mp->number_of_evasions(); }
+
+      RootMoveList::iterator rm; // Dummy, never used
+      MovePicker* mp;
+  };
+
+  // Normal case, create and use a MovePicker object as source
+  template<> struct MovePickerExt<false, false> : public MovePicker {
+
+      MovePickerExt(const Position& p, Move ttm, Depth d, const History& h,
+                    SearchStack* ss, Value beta) : MovePicker(p, ttm, d, h, ss, beta) {}
+
+      RootMoveList::iterator rm; // Dummy, never used
+  };
+
+} // namespace
 
 
 ////
@@ -403,7 +452,7 @@ int64_t perft(Position& pos, Depth depth)
 
 /// think() is the external interface to Stockfish's search, and is called when
 /// the program receives the UCI 'go' command. It initializes various
-/// search-related global variables, and calls root_search(). It returns false
+/// search-related global variables, and calls id_loop(). It returns false
 /// when a quit command is received during the search.
 
 bool think(Position& pos, bool infinite, bool ponder, int time[], int increment[],
@@ -545,7 +594,7 @@ bool think(Position& pos, bool infinite, bool ponder, int time[], int increment[
 
 namespace {
 
-  // id_loop() is the main iterative deepening loop. It calls root_search
+  // id_loop() is the main iterative deepening loop. It calls search()
   // repeatedly with increasing depth until the allocated thinking time has
   // been consumed, the user stops the search, or the maximum search depth is
   // reached.
@@ -560,6 +609,7 @@ namespace {
 
     // Moves to search are verified, scored and sorted
     RootMoveList rml(pos, searchMoves);
+    Rml = &rml;
 
     // Handle special case of searching on a mate/stale position
     if (rml.size() == 0)
@@ -624,7 +674,15 @@ namespace {
             rml.sort();
 
             // Search to the current depth, rml is updated and sorted
-            value = root_search(pos, ss, alpha, beta, depth, rml);
+            value = search<PV, false, true>(pos, ss, alpha, beta, depth, 0);
+
+            // Sort the moves before to return
+            rml.sort();
+
+            // Write PV lines to transposition table, in case the relevant entries
+            // have been overwritten during the search.
+            for (int i = 0; i < Min(MultiPV, (int)rml.size()); i++)
+                rml[i].insert_pv_in_tt(pos);
 
             if (StopRequest)
                 break;
@@ -714,236 +772,6 @@ namespace {
   }
 
 
-  // root_search() is the function which searches the root node. It is
-  // similar to search_pv except that it prints some information to the
-  // standard output and handles the fail low/high loops.
-
-  Value root_search(Position& pos, SearchStack* ss, Value alpha,
-                    Value beta, Depth depth, RootMoveList& rml) {
-
-    assert(alpha >= -VALUE_INFINITE && alpha <= VALUE_INFINITE);
-    assert(beta > alpha && beta <= VALUE_INFINITE);
-    assert(pos.thread() >= 0 && pos.thread() < ThreadsMgr.active_threads());
-
-    Move movesSearched[MOVES_MAX];
-    StateInfo st;
-    Key posKey;
-    Move move;
-    Depth ext, newDepth;
-    ValueType vt;
-    Value value, oldAlpha;
-    bool isCheck, moveIsCheck, captureOrPromotion, dangerous, isPvMove;
-    int moveCount = 0;
-
-    value = -VALUE_INFINITE;
-    oldAlpha = alpha;
-    isCheck = pos.is_check();
-
-    // Step 1. Initialize node (polling is omitted at root)
-    ss->currentMove = ss->bestMove = MOVE_NONE;
-    (ss+2)->killers[0] = (ss+2)->killers[1] = (ss+2)->mateKiller = MOVE_NONE;
-
-    // Step 2. Check for aborted search (omitted at root)
-    // Step 3. Mate distance pruning (omitted at root)
-    // Step 4. Transposition table lookup (omitted at root)
-    posKey = pos.get_key();
-
-    // Step 5. Evaluate the position statically
-    // At root we do this only to get reference value for child nodes
-    ss->evalMargin = VALUE_NONE;
-    ss->eval = isCheck ? VALUE_NONE : evaluate(pos, ss->evalMargin);
-
-    // Step 6. Razoring (omitted at root)
-    // Step 7. Static null move pruning (omitted at root)
-    // Step 8. Null move search with verification search (omitted at root)
-    // Step 9. Internal iterative deepening (omitted at root)
-
-    CheckInfo ci(pos);
-    int64_t nodes;
-    RootMoveList::iterator rm = rml.begin();
-
-    // Step 10. Loop through moves
-    // Loop through all legal moves until no moves remain or a beta cutoff occurs
-    while (   alpha < beta
-           && rm != rml.end()
-           && !StopRequest)
-    {
-        move = ss->currentMove = rm->pv[0];
-        movesSearched[moveCount++] = move;
-        isPvMove = (moveCount <= MultiPV);
-
-        // This is used by time management
-        FirstRootMove = (rm == rml.begin());
-
-        // Save the current node count before the move is searched
-        nodes = pos.nodes_searched();
-
-        // If it's time to send nodes info, do it here where we have the
-        // correct accumulated node counts searched by each thread.
-        if (SendSearchedNodes)
-        {
-            SendSearchedNodes = false;
-            cout << "info nodes " << nodes
-                 << " nps " << nps(pos)
-                 << " time " << current_search_time() << endl;
-        }
-
-        if (current_search_time() >= 1000)
-            cout << "info currmove " << move
-                 << " currmovenumber " << moveCount << endl;
-
-        moveIsCheck = pos.move_is_check(move);
-        captureOrPromotion = pos.move_is_capture_or_promotion(move);
-
-        // Step 11. Decide the new search depth
-        ext = extension<PV>(pos, move, captureOrPromotion, moveIsCheck, false, false, &dangerous);
-        newDepth = depth + ext;
-
-        // Step 12. Futility pruning (omitted at root)
-        // Step 13. Make the move
-        pos.do_move(move, st, ci, moveIsCheck);
-
-        // Step extra. pv search
-        // We do pv search for PV moves
-        if (isPvMove)
-        {
-            // Aspiration window is disabled in multi-pv case
-            if (MultiPV > 1)
-                alpha = -VALUE_INFINITE;
-
-            // Full depth PV search, done on first move or after a fail high
-            value = -search<PV>(pos, ss+1, -beta, -alpha, newDepth, 1);
-        }
-        else
-        {
-            // Step 14. Reduced search
-            // if the move fails high will be re-searched at full depth
-            bool doFullDepthSearch = true;
-
-            if (    depth >= 3 * ONE_PLY
-                && !captureOrPromotion
-                && !dangerous
-                && !move_is_castle(move)
-                &&  ss->killers[0] != move
-                &&  ss->killers[1] != move)
-            {
-                ss->reduction = reduction<PV>(depth, moveCount - MultiPV + 1);
-
-                if (ss->reduction)
-                {
-                    Depth d = newDepth - ss->reduction;
-                    value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, 1);
-
-                    doFullDepthSearch = (value > alpha);
-                }
-                ss->reduction = DEPTH_ZERO; // Restore original reduction
-            }
-
-            // Step 15. Full depth search
-            if (doFullDepthSearch)
-            {
-                // Full depth non-pv search using alpha as upperbound
-                value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, 1);
-
-                // If we are above alpha then research at same depth but as PV
-                // to get a correct score or eventually a fail high above beta.
-                if (value > alpha)
-                    value = -search<PV>(pos, ss+1, -beta, -alpha, newDepth, 1);
-            }
-        }
-
-        // Step 16. Undo move
-        pos.undo_move(move);
-
-        assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
-
-        // Finished searching the move. If StopRequest is true, the search
-        // was aborted because the user interrupted the search or because we
-        // ran out of time. In this case, the return value of the search cannot
-        // be trusted, and we break out of the loop without updating the best
-        // move and/or PV.
-        if (StopRequest)
-            break;
-
-        // Remember searched nodes counts for this move
-        rm->nodes += pos.nodes_searched() - nodes;
-
-        // Step 17. Check for new best move
-        if (!isPvMove && value <= alpha)
-            rm->pv_score = -VALUE_INFINITE;
-        else
-        {
-            // PV move or new best move!
-
-            // Update PV
-            ss->bestMove = move;
-            rm->pv_score = value;
-            rm->extract_pv_from_tt(pos);
-
-            // We record how often the best move has been changed in each
-            // iteration. This information is used for time managment: When
-            // the best move changes frequently, we allocate some more time.
-            if (!isPvMove && MultiPV == 1)
-                BestMoveChangesByIteration[Iteration]++;
-
-            // Inform GUI that PV has changed, in case of multi-pv UCI protocol
-            // requires we send all the PV lines properly sorted.
-            rml.sort_multipv(moveCount);
-
-            for (int j = 0; j < Min(MultiPV, (int)rml.size()); j++)
-                cout << rml[j].pv_info_to_uci(pos, alpha, beta, j) << endl;
-
-            // Update alpha. In multi-pv we don't use aspiration window
-            if (MultiPV == 1)
-            {
-                // Raise alpha to setup proper non-pv search upper bound
-                if (value > alpha)
-                    alpha = value;
-            }
-            else // Set alpha equal to minimum score among the PV lines
-                alpha = rml[Min(moveCount, MultiPV) - 1].pv_score; // FIXME why moveCount?
-
-        } // PV move or new best move
-
-        ++rm;
-
-    } // Root moves loop
-
-
-    // Step 20. Update tables
-    // If the search is not aborted, update the transposition table,
-    // history counters, and killer moves.
-    if (!StopRequest)
-    {
-        move = alpha <= oldAlpha ? MOVE_NONE : ss->bestMove;
-        vt   = alpha <= oldAlpha ? VALUE_TYPE_UPPER
-                                 : alpha >= beta ? VALUE_TYPE_LOWER : VALUE_TYPE_EXACT;
-
-        TT.store(posKey, value_to_tt(alpha, 0), vt, depth, move, ss->eval, ss->evalMargin);
-
-        // Update killers and history only for non capture moves that fails high
-        if (    alpha >= beta
-            && !pos.move_is_capture_or_promotion(move))
-        {
-            update_history(pos, move, depth, movesSearched, moveCount);
-            update_killers(move, ss->killers);
-        }
-    }
-
-    // Sort the moves before to return
-    rml.sort();
-
-    // Write PV lines to transposition table, in case the relevant entries
-    // have been overwritten during the search.
-    for (int i = 0; i < Min(MultiPV, (int)rml.size()); i++)
-        rml[i].insert_pv_in_tt(pos);
-
-    assert(alpha > -VALUE_INFINITE && alpha < VALUE_INFINITE);
-
-    return alpha;
-  }
-
-
   // search<>() is the main search function for both PV and non-PV nodes and for
   // normal and SplitPoint nodes. When called just after a split point the search
   // is simpler because we have already probed the hash table, done a null move
@@ -951,16 +779,17 @@ namespace {
   // all this work again. We also don't need to store anything to the hash table
   // here: This is taken care of after we return from the split point.
 
-  template <NodeType PvNode, bool SpNode>
+  template <NodeType PvNode, bool SpNode, bool Root>
   Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply) {
 
     assert(alpha >= -VALUE_INFINITE && alpha <= VALUE_INFINITE);
     assert(beta > alpha && beta <= VALUE_INFINITE);
     assert(PvNode || alpha == beta - 1);
-    assert(ply > 0 && ply < PLY_MAX);
+    assert((Root || ply > 0) && ply < PLY_MAX);
     assert(pos.thread() >= 0 && pos.thread() < ThreadsMgr.active_threads());
 
     Move movesSearched[MOVES_MAX];
+    int64_t nodes;
     StateInfo st;
     const TTEntry *tte;
     Key posKey;
@@ -969,11 +798,12 @@ namespace {
     ValueType vt;
     Value bestValue, value, oldAlpha;
     Value refinedValue, nullValue, futilityBase, futilityValueScaled; // Non-PV specific
-    bool isCheck, singleEvasion, singularExtensionNode, moveIsCheck, captureOrPromotion, dangerous;
+    bool isPvMove, isCheck, singleEvasion, singularExtensionNode, moveIsCheck, captureOrPromotion, dangerous;
     bool mateThreat = false;
     int moveCount = 0;
     int threadID = pos.thread();
     SplitPoint* sp = NULL;
+
     refinedValue = bestValue = value = -VALUE_INFINITE;
     oldAlpha = alpha;
     isCheck = pos.is_check();
@@ -993,24 +823,27 @@ namespace {
     ss->currentMove = ss->bestMove = threatMove = MOVE_NONE;
     (ss+2)->killers[0] = (ss+2)->killers[1] = (ss+2)->mateKiller = MOVE_NONE;
 
-    if (threadID == 0 && ++NodesSincePoll > NodesBetweenPolls)
+    if (!Root)
     {
-        NodesSincePoll = 0;
-        poll(pos);
-    }
-
-    // Step 2. Check for aborted search and immediate draw
-    if (   StopRequest
-        || ThreadsMgr.cutoff_at_splitpoint(threadID)
-        || pos.is_draw()
-        || ply >= PLY_MAX - 1)
-        return VALUE_DRAW;
+        if (threadID == 0 && ++NodesSincePoll > NodesBetweenPolls)
+        {
+            NodesSincePoll = 0;
+            poll(pos);
+        }
 
-    // Step 3. Mate distance pruning
-    alpha = Max(value_mated_in(ply), alpha);
-    beta = Min(value_mate_in(ply+1), beta);
-    if (alpha >= beta)
-        return alpha;
+        // Step 2. Check for aborted search and immediate draw
+        if (   StopRequest
+            || ThreadsMgr.cutoff_at_splitpoint(threadID)
+            || pos.is_draw()
+            || ply >= PLY_MAX - 1)
+            return VALUE_DRAW;
+
+        // Step 3. Mate distance pruning
+        alpha = Max(value_mated_in(ply), alpha);
+        beta = Min(value_mate_in(ply+1), beta);
+        if (alpha >= beta)
+            return alpha;
+    }
 
     // Step 4. Transposition table lookup
 
@@ -1055,7 +888,8 @@ namespace {
     }
 
     // Save gain for the parent non-capture move
-    update_gains(pos, (ss-1)->currentMove, (ss-1)->eval, ss->eval);
+    if (!Root)
+        update_gains(pos, (ss-1)->currentMove, (ss-1)->eval, ss->eval);
 
     // Step 6. Razoring (is omitted in PV nodes)
     if (   !PvNode
@@ -1148,7 +982,8 @@ namespace {
     }
 
     // Step 9. Internal iterative deepening
-    if (    depth >= IIDDepth[PvNode]
+    if (   !Root
+        &&  depth >= IIDDepth[PvNode]
         &&  ttMove == MOVE_NONE
         && (PvNode || (!isCheck && ss->eval >= beta - IIDMargin)))
     {
@@ -1163,26 +998,28 @@ namespace {
     }
 
     // Expensive mate threat detection (only for PV nodes)
-    if (PvNode)
+    if (PvNode && !Root) // FIXME
         mateThreat = pos.has_mate_threat();
 
 split_point_start: // At split points actual search starts from here
 
     // Initialize a MovePicker object for the current position
-    // FIXME currently MovePicker() c'tor is needless called also in SplitPoint
-    MovePicker mpBase(pos, ttMove, depth, H, ss, (PvNode ? -VALUE_INFINITE : beta));
-    MovePicker& mp = SpNode ? *sp->mp : mpBase;
+    MovePickerExt<SpNode, Root> mp(pos, ttMove, depth, H, ss, (PvNode ? -VALUE_INFINITE : beta));
     CheckInfo ci(pos);
     ss->bestMove = MOVE_NONE;
     singleEvasion = !SpNode && isCheck && mp.number_of_evasions() == 1;
     futilityBase = ss->eval + ss->evalMargin;
-    singularExtensionNode =  !SpNode
+    singularExtensionNode =   !Root
+                           && !SpNode
                            && depth >= SingularExtensionDepth[PvNode]
                            && tte
                            && tte->move()
                            && !excludedMove // Do not allow recursive singular extension search
                            && (tte->type() & VALUE_TYPE_LOWER)
                            && tte->depth() >= depth - 3 * ONE_PLY;
+    if (Root)
+        bestValue = alpha;
+
     if (SpNode)
     {
         lock_grab(&(sp->lock));
@@ -1207,6 +1044,30 @@ split_point_start: // At split points actual search starts from here
       else
           movesSearched[moveCount++] = move;
 
+      if (Root)
+      {
+          // This is used by time management
+          FirstRootMove = (moveCount == 1);
+
+          // Save the current node count before the move is searched
+          nodes = pos.nodes_searched();
+
+          // If it's time to send nodes info, do it here where we have the
+          // correct accumulated node counts searched by each thread.
+          if (SendSearchedNodes)
+          {
+              SendSearchedNodes = false;
+              cout << "info nodes " << nodes
+                   << " nps " << nps(pos)
+                   << " time " << current_search_time() << endl;
+          }
+
+          if (current_search_time() >= 1000)
+              cout << "info currmove " << move
+                   << " currmovenumber " << moveCount << endl;
+      }
+
+      isPvMove = (PvNode && moveCount <= (Root ? MultiPV : 1));
       moveIsCheck = pos.move_is_check(move, ci);
       captureOrPromotion = pos.move_is_capture_or_promotion(move);
 
@@ -1239,7 +1100,7 @@ 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;
+      newDepth = depth - (!Root ? ONE_PLY : DEPTH_ZERO) + ext;
 
       // Step 12. Futility pruning (is omitted in PV nodes)
       if (   !PvNode
@@ -1298,8 +1159,14 @@ split_point_start: // At split points actual search starts from here
 
       // Step extra. pv search (only in PV nodes)
       // The first move in list is the expected PV
-      if (PvNode && moveCount == 1)
+      if (isPvMove)
+      {
+          // Aspiration window is disabled in multi-pv case
+          if (Root && MultiPV > 1)
+              alpha = -VALUE_INFINITE;
+
           value = -search<PV>(pos, ss+1, -beta, -alpha, newDepth, ply+1);
+      }
       else
       {
           // Step 14. Reduced depth search
@@ -1313,8 +1180,8 @@ split_point_start: // At split points actual search starts from here
               &&  ss->killers[0] != move
               &&  ss->killers[1] != move)
           {
-              ss->reduction = reduction<PvNode>(depth, moveCount);
-
+              ss->reduction = Root ? reduction<PvNode>(depth, moveCount - MultiPV + 1)
+                                   : reduction<PvNode>(depth, moveCount);
               if (ss->reduction)
               {
                   alpha = SpNode ? sp->alpha : alpha;
@@ -1335,7 +1202,7 @@ split_point_start: // At split points actual search starts from here
               // Step extra. pv search (only in PV nodes)
               // Search only for possible new PV nodes, if instead value >= beta then
               // parent node fails low with value <= alpha and tries another move.
-              if (PvNode && value > alpha && value < beta)
+              if (PvNode && value > alpha && (Root || value < beta))
                   value = -search<PV>(pos, ss+1, -beta, -alpha, newDepth, ply+1);
           }
       }
@@ -1353,7 +1220,7 @@ split_point_start: // At split points actual search starts from here
           alpha = sp->alpha;
       }
 
-      if (value > bestValue && !(SpNode && ThreadsMgr.cutoff_at_splitpoint(threadID)))
+      if (!Root && value > bestValue && !(SpNode && ThreadsMgr.cutoff_at_splitpoint(threadID)))
       {
           bestValue = value;
 
@@ -1382,8 +1249,60 @@ split_point_start: // At split points actual search starts from here
           }
       }
 
+      if (Root)
+      {
+          // Finished searching the move. If StopRequest is true, the search
+          // was aborted because the user interrupted the search or because we
+          // ran out of time. In this case, the return value of the search cannot
+          // be trusted, and we break out of the loop without updating the best
+          // move and/or PV.
+          if (StopRequest)
+              break;
+
+          // Remember searched nodes counts for this move
+          mp.rm->nodes += pos.nodes_searched() - nodes;
+
+          // Step 17. Check for new best move
+          if (!isPvMove && value <= alpha)
+              mp.rm->pv_score = -VALUE_INFINITE;
+          else
+          {
+              // PV move or new best move!
+
+              // Update PV
+              ss->bestMove = move;
+              mp.rm->pv_score = value;
+              mp.rm->extract_pv_from_tt(pos);
+
+              // We record how often the best move has been changed in each
+              // iteration. This information is used for time managment: When
+              // the best move changes frequently, we allocate some more time.
+              if (!isPvMove && MultiPV == 1)
+                  BestMoveChangesByIteration[Iteration]++;
+
+              // Inform GUI that PV has changed, in case of multi-pv UCI protocol
+              // requires we send all the PV lines properly sorted.
+              Rml->sort_multipv(moveCount);
+
+              for (int j = 0; j < Min(MultiPV, (int)Rml->size()); j++)
+                  cout << (*Rml)[j].pv_info_to_uci(pos, alpha, beta, j) << endl;
+
+              // Update alpha. In multi-pv we don't use aspiration window
+              if (MultiPV == 1)
+              {
+                  // Raise alpha to setup proper non-pv search upper bound
+                  if (value > alpha)
+                      alpha = bestValue = value;
+              }
+              else // Set alpha equal to minimum score among the PV lines
+                  alpha = bestValue = (*Rml)[Min(moveCount, MultiPV) - 1].pv_score; // FIXME why moveCount?
+
+          } // PV move or new best move
+      }
+
       // Step 18. Check for split
-      if (   !SpNode
+      if (   !Root
+          && !SpNode
           && depth >= ThreadsMgr.min_split_depth()
           && ThreadsMgr.active_threads() > 1
           && bestValue < beta
@@ -1392,7 +1311,7 @@ split_point_start: // At split points actual search starts from here
           && !ThreadsMgr.cutoff_at_splitpoint(threadID)
           && Iteration <= 99)
           ThreadsMgr.split<FakeSplit>(pos, ss, ply, &alpha, beta, &bestValue, depth,
-                                      threatMove, mateThreat, moveCount, &mp, PvNode);
+                                      threatMove, mateThreat, moveCount, (MovePicker*)&mp, PvNode);
     }
 
     // Step 19. Check for mate and stalemate
@@ -2238,9 +2157,9 @@ split_point_start: // At split points actual search starts from here
             ss->sp = tsp;
 
             if (tsp->pvNode)
-                search<PV, true>(pos, ss, tsp->alpha, tsp->beta, tsp->depth, tsp->ply);
+                search<PV, true, false>(pos, ss, tsp->alpha, tsp->beta, tsp->depth, tsp->ply);
             else
-                search<NonPV, true>(pos, ss, tsp->alpha, tsp->beta, tsp->depth, tsp->ply);
+                search<NonPV, true, false>(pos, ss, tsp->alpha, tsp->beta, tsp->depth, tsp->ply);
 
             assert(threads[threadID].state == THREAD_SEARCHING);