+ // Write PV to transposition table, in case the relevant entries have
+ // been overwritten during the search:
+ TT.insert_pv(p, ss[0].pv);
+
+ if (AbortSearch)
+ break; //Value cannot be trusted. Break out immediately!
+
+ //Save info about search result
+ Value speculated_value = value;
+ bool fHigh = false;
+ bool fLow = false;
+
+ Value prev_value = IterationInfo[Iteration - 1].value();
+ Value delta = value - prev_value;
+
+ if (value >= beta) {
+ fHigh = true;
+ speculated_value = prev_value + 2 * delta;
+ BestMoveChangesByIteration[Iteration] += 2; //This is used to tell time management to allocate more time
+ } else if (value <= alpha) {
+ fLow = true;
+ speculated_value = prev_value + 2 * delta;
+ BestMoveChangesByIteration[Iteration] += 3; //This is used to tell time management to allocate more time
+ } else {
+ //nothing
+ }
+
+ if (speculated_value < - VALUE_INFINITE) speculated_value = - VALUE_INFINITE;
+ if (speculated_value > VALUE_INFINITE) speculated_value = VALUE_INFINITE;
+
+ IterationInfo[Iteration].set(value, speculated_value, fHigh, fLow);
+
+ // Erase the easy move if it differs from the new best move
+ if (ss[0].pv[0] != EasyMove)
+ EasyMove = MOVE_NONE;
+
+ Problem = false;
+
+ if (!InfiniteSearch)
+ {
+ // Time to stop?
+ bool stopSearch = false;
+
+ // Stop search early if there is only a single legal move:
+ if (Iteration >= 6 && rml.move_count() == 1)
+ stopSearch = true;
+
+ // Stop search early when the last two iterations returned a mate score
+ if ( Iteration >= 6
+ && abs(IterationInfo[Iteration].value()) >= abs(VALUE_MATE) - 100
+ && abs(IterationInfo[Iteration-1].value()) >= abs(VALUE_MATE) - 100)
+ stopSearch = true;
+
+ // Stop search early if one move seems to be much better than the rest
+ int64_t nodes = nodes_searched();
+ if ( Iteration >= 8 && !fLow && !fHigh
+ && EasyMove == ss[0].pv[0]
+ && ( ( rml.get_move_cumulative_nodes(0) > (nodes * 85) / 100
+ && current_search_time() > MaxSearchTime / 16)
+ ||( rml.get_move_cumulative_nodes(0) > (nodes * 98) / 100
+ && current_search_time() > MaxSearchTime / 32)))
+ stopSearch = true;
+
+ // Add some extra time if the best move has changed during the last two iterations
+ if (Iteration > 5 && Iteration <= 50)
+ ExtraSearchTime = BestMoveChangesByIteration[Iteration] * (MaxSearchTime / 2)
+ + BestMoveChangesByIteration[Iteration-1] * (MaxSearchTime / 3);
+
+ // Stop search if most of MaxSearchTime is consumed at the end of the
+ // iteration. We probably don't have enough time to search the first
+ // move at the next iteration anyway.
+ if (current_search_time() > ((MaxSearchTime + ExtraSearchTime)*80) / 128)
+ stopSearch = true;
+
+ if (stopSearch)
+ {
+ if (!PonderSearch)
+ break;
+ else
+ StopOnPonderhit = true;
+ }
+ }
+
+ if (MaxDepth && Iteration >= MaxDepth)
+ break;
+ }
+
+ if (FailLow)
+ {
+ //Here we face the rare, but extremely difficult case:
+ //Our aspiration search has failed low and we've run out of time!
+ //So we have no move to play!
+ //Now use the emergency time and try as quickly as possible to
+ //find even one playable move.
+
+ //FIXME: this is only for grepping logs purpose. Remove me when we are sure that this stuff really works!!
+ if (AbortSearch)
+ std::cout << "info depth " << 999 << std::endl;
+ else
+ std::cout << "info depth " << 998 << std::endl;
+
+ //Prepare variables for emergency search
+ AbortSearch = false;
+ FailLow = false;
+ AbsoluteMaxSearchTime = EmergencyMaxSearchTime;
+ MaxSearchTime = EmergencyMaxSearchTime;
+ ExtraSearchTime = 0;
+ rml.sort();
+
+ std::cout << "info depth " << Iteration << std::endl;
+
+ //Cause we failed low, it's _likely_ that we couldn't get over alpha anyway.
+ root_search(p, ss, rml, -VALUE_INFINITE, alpha);