- }
-
- 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 " << TM.nodes_searched()
- << " nps " << nps()
- << " time " << current_search_time() << endl;
-
- // Print the best move and the ponder move to the standard output
- if (pv[0] == MOVE_NONE)
- {
- pv[0] = rml.get_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: " << TM.nodes_searched()
- << "\nNodes/second: " << nps()
- << "\nBest move: " << move_to_san(p, pv[0]);
-
- StateInfo st;
- p.do_move(pv[0], st);
- LogFile << "\nPonder move: "
- << move_to_san(p, pv[1]) // Works also with MOVE_NONE
- << endl;
- }
- return rml.get_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) {
-
- EvalInfo ei;
- 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();
-
- // 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->eval = isCheck ? VALUE_NONE : evaluate(pos, ei);
-
- // 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.sort();
-
- // Step 10. Loop through all moves in the root move list
- for (int i = 0; i < rml.move_count() && !AbortSearch; i++)
- {
- // This is used by time management
- FirstRootMove = (i == 0);
-
- // Save the current node count before the move is searched
- nodes = TM.nodes_searched();
-
- // Reset beta cut-off counters
- TM.resetBetaCounters();
-
- // Pick the next root move, and print the move and the move number to
- // the standard output.
- move = ss->currentMove = rml.get_move(i);
-
- if (current_search_time() >= 1000)
- cout << "info currmove " << move
- << " currmovenumber " << i + 1 << endl;
-
- moveIsCheck = pos.move_is_check(move);
- captureOrPromotion = pos.move_is_capture_or_promotion(move);
-
- // Step 11. Decide the new search depth
- depth = (Iteration - 2) * OnePly + InitialDepth;
- ext = extension<PV>(pos, move, captureOrPromotion, moveIsCheck, false, false, &dangerous);
- newDepth = depth + ext;
-
- // Step 12. Futility pruning (omitted at root)
-
- // Step extra. Fail high loop
- // If move fails high, we research with bigger window until we are not failing
- // high anymore.
- value = - VALUE_INFINITE;
-
- while (1)