-
- // We are failing high and going to do a research. It's important to update score
- // before research in case we run out of time while researching.
- rml.set_move_score(i, value);
- update_pv(ss, 0);
- TT.extract_pv(pos, ss[0].pv, PLY_MAX);
- rml.set_move_pv(i, ss[0].pv);
-
- // Print search information to the standard output
- cout << "info depth " << Iteration
- << " score " << value_to_string(value)
- << ((value >= beta) ? " lowerbound" :
- ((value <= alpha)? " upperbound" : ""))
- << " time " << current_search_time()
- << " nodes " << TM.nodes_searched()
- << " nps " << nps()
- << " pv ";
-
- for (int j = 0; ss[0].pv[j] != MOVE_NONE && j < PLY_MAX; j++)
- cout << ss[0].pv[j] << " ";
-
- cout << endl;
-
- if (UseLogFile)
- {
- ValueType type = (value >= beta ? VALUE_TYPE_LOWER
- : (value <= alpha ? VALUE_TYPE_UPPER : VALUE_TYPE_EXACT));
-
- LogFile << pretty_pv(pos, current_search_time(), Iteration,
- TM.nodes_searched(), value, type, ss[0].pv) << endl;
- }
-
- // Prepare for a research after a fail high, each time with a wider window
- researchCount++;
- beta = Min(beta + AspirationDelta * (1 << researchCount), VALUE_INFINITE);
-
- } // End of fail high loop
-
- // Finished searching the move. If AbortSearch 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 (AbortSearch)
- break;
-
- // Remember beta-cutoff and searched nodes counts for this move. The
- // info is used to sort the root moves at the next iteration.
- int64_t our, their;
- TM.get_beta_counters(pos.side_to_move(), our, their);
- rml.set_beta_counters(i, our, their);
- rml.set_move_nodes(i, TM.nodes_searched() - nodes);
-
- assert(value >= -VALUE_INFINITE && value <= VALUE_INFINITE);
-
- if (value <= alpha && i >= MultiPV)
- rml.set_move_score(i, -VALUE_INFINITE);
- else
- {
- // PV move or new best move!
-
- // Update PV
- rml.set_move_score(i, value);
- update_pv(ss, 0);
- TT.extract_pv(pos, ss[0].pv, PLY_MAX);
- rml.set_move_pv(i, ss[0].pv);
-
- if (MultiPV == 1)
- {
- // 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 (i > 0)
- BestMoveChangesByIteration[Iteration]++;
-
- // Print search information to the standard output
- cout << "info depth " << Iteration
- << " score " << value_to_string(value)
- << ((value >= beta) ? " lowerbound" :
- ((value <= alpha)? " upperbound" : ""))
- << " time " << current_search_time()
- << " nodes " << TM.nodes_searched()
- << " nps " << nps()
- << " pv ";
-
- for (int j = 0; ss[0].pv[j] != MOVE_NONE && j < PLY_MAX; j++)
- cout << ss[0].pv[j] << " ";
-
- cout << endl;
-
- if (UseLogFile)
- {
- ValueType type = (value >= beta ? VALUE_TYPE_LOWER
- : (value <= alpha ? VALUE_TYPE_UPPER : VALUE_TYPE_EXACT));
-
- LogFile << pretty_pv(pos, current_search_time(), Iteration,
- TM.nodes_searched(), value, type, ss[0].pv) << endl;
- }
- if (value > alpha)
- alpha = value;
- }
- else // MultiPV > 1
- {
- rml.sort_multipv(i);
- for (int j = 0; j < Min(MultiPV, rml.move_count()); j++)
- {
- cout << "info multipv " << j + 1
- << " score " << value_to_string(rml.get_move_score(j))
- << " depth " << ((j <= i)? Iteration : Iteration - 1)
- << " time " << current_search_time()
- << " nodes " << TM.nodes_searched()
- << " nps " << nps()
- << " pv ";
-
- for (int k = 0; rml.get_move_pv(j, k) != MOVE_NONE && k < PLY_MAX; k++)
- cout << rml.get_move_pv(j, k) << " ";
-
- cout << endl;
- }
- alpha = rml.get_move_score(Min(i, MultiPV-1));
- }
- } // PV move or new best move
-
- assert(alpha >= oldAlpha);
-
- AspirationFailLow = (alpha == oldAlpha);
-
- if (AspirationFailLow && StopOnPonderhit)
- StopOnPonderhit = false;