- }
-
- if (MaxDepth && Iteration >= MaxDepth)
- break;
- }
-
- // If we are pondering or in infinite search, we shouldn't print the
- // best move before we are told to do so.
- if (!AbortSearch && (PonderSearch || InfiniteSearch))
- wait_for_stop_or_ponderhit();
- else
- // Print final search statistics
- cout << "info nodes " << pos.nodes_searched()
- << " nps " << nps(pos)
- << " time " << current_search_time() << endl;
-
- // Print the best move and the ponder move to the standard output
- if (pv[0] == MOVE_NONE || MultiPV > 1)
- {
- pv[0] = rml.move(0);
- pv[1] = MOVE_NONE;
- }
-
- assert(pv[0] != MOVE_NONE);
-
- cout << "bestmove " << pv[0];
-
- if (pv[1] != MOVE_NONE)
- cout << " ponder " << pv[1];
-
- cout << endl;
-
- if (UseLogFile)
- {
- if (dbg_show_mean)
- dbg_print_mean(LogFile);
-
- if (dbg_show_hit_rate)
- dbg_print_hit_rate(LogFile);
-
- LogFile << "\nNodes: " << pos.nodes_searched()
- << "\nNodes/second: " << nps(pos)
- << "\nBest move: " << move_to_san(pos, pv[0]);
-
- StateInfo st;
- pos.do_move(pv[0], st);
- LogFile << "\nPonder move: "
- << move_to_san(pos, pv[1]) // Works also with MOVE_NONE
- << endl;
- }
- return rml.move_score(0);
- }
-
-
- // root_search() is the function which searches the root node. It is
- // similar to search_pv except that it uses a different move ordering
- // scheme, prints some information to the standard output and handles
- // the fail low/high loops.
-
- Value root_search(Position& pos, SearchStack* ss, Move* pv, RootMoveList& rml, Value* alphaPtr, Value* betaPtr) {
-
- StateInfo st;
- CheckInfo ci(pos);
- int64_t nodes;
- Move move;
- Depth depth, ext, newDepth;
- Value value, alpha, beta;
- bool isCheck, moveIsCheck, captureOrPromotion, dangerous;
- int researchCountFH, researchCountFL;
-
- researchCountFH = researchCountFL = 0;
- alpha = *alphaPtr;
- beta = *betaPtr;
- isCheck = pos.is_check();
- depth = (Iteration - 2) * ONE_PLY + InitialDepth;
-
- // Step 1. Initialize node (polling is omitted at root)
- ss->currentMove = ss->bestMove = 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)
-
- // 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)
-
- // Step extra. Fail low loop
- // We start with small aspiration window and in case of fail low, we research
- // with bigger window until we are not failing low anymore.
- while (1)
- {
- // Sort the moves before to (re)search
- rml.score_moves(pos);
- rml.sort();