X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fsearch.cpp;h=d75036b33413eee1705200ed6905c7df1aa60570;hb=22ca7a601f8484d03eb7e9be79e03a74d2e4aa2c;hp=6ec051987d98663a775252e74f77e52f52f8575e;hpb=6df86fc9dadcd02fef82605027156dbea6832d29;p=stockfish diff --git a/src/search.cpp b/src/search.cpp index 6ec05198..d75036b3 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -149,7 +149,7 @@ namespace { void set_non_pv_scores(const Position& pos); void sort() { insertion_sort(begin(), end()); } - void sort_multipv(int n) { insertion_sort(begin(), begin() + n); } + void sort_multipv(int n) { insertion_sort(begin(), begin() + n + 1); } }; @@ -513,6 +513,9 @@ bool think(Position& pos, bool infinite, bool ponder, int time[], int increment[ << move_to_san(pos, ponderMove) // Works also with MOVE_NONE << endl; + // Return from think() with unchanged position + pos.undo_move(bestMove); + LogFile.close(); } @@ -713,10 +716,10 @@ namespace { rml.sort(); // Step 10. Loop through all moves in the root move list - for (int i = 0; i < (int)rml.size() && !StopRequest; i++) + for (int moveCount = 0; moveCount < (int)rml.size() && !StopRequest; moveCount++) { // This is used by time management - FirstRootMove = (i == 0); + FirstRootMove = (moveCount == 0); // Save the current node count before the move is searched nodes = pos.nodes_searched(); @@ -733,11 +736,11 @@ namespace { // Pick the next root move, and print the move and the move number to // the standard output. - move = ss->currentMove = rml[i].pv[0]; + move = ss->currentMove = rml[moveCount].pv[0]; if (current_search_time() >= 1000) cout << "info currmove " << move - << " currmovenumber " << i + 1 << endl; + << " currmovenumber " << moveCount + 1 << endl; moveIsCheck = pos.move_is_check(move); captureOrPromotion = pos.move_is_capture_or_promotion(move); @@ -761,7 +764,7 @@ namespace { // Step extra. pv search // We do pv search for first moves (i < MultiPV) // and for fail high research (value > alpha) - if (i < MultiPV || value > alpha) + if (moveCount < MultiPV || value > alpha) { // Aspiration window is disabled in multi-pv case if (MultiPV > 1) @@ -781,7 +784,7 @@ namespace { && !captureOrPromotion && !move_is_castle(move)) { - ss->reduction = reduction(depth, i - MultiPV + 2); + ss->reduction = reduction(depth, moveCount - MultiPV + 2); if (ss->reduction) { assert(newDepth-ss->reduction >= ONE_PLY); @@ -816,11 +819,11 @@ namespace { // We are failing high and going to do a research. It's important to update // the score before research in case we run out of time while researching. ss->bestMove = move; - rml[i].pv_score = value; - rml[i].extract_pv_from_tt(pos); + rml[moveCount].pv_score = value; + rml[moveCount].extract_pv_from_tt(pos); // Inform GUI that PV has changed - cout << rml[i].pv_info_to_uci(pos, alpha, beta) << endl; + cout << rml[moveCount].pv_info_to_uci(pos, alpha, beta) << endl; // Prepare for a research after a fail high, each time with a wider window beta = Min(beta + AspirationDelta * (1 << researchCountFH), VALUE_INFINITE); @@ -837,32 +840,32 @@ namespace { break; // Remember searched nodes counts for this move - rml[i].nodes += pos.nodes_searched() - nodes; + rml[moveCount].nodes += pos.nodes_searched() - nodes; assert(value >= -VALUE_INFINITE && value <= VALUE_INFINITE); assert(value < beta); // Step 17. Check for new best move - if (value <= alpha && i >= MultiPV) - rml[i].pv_score = -VALUE_INFINITE; + if (value <= alpha && moveCount >= MultiPV) + rml[moveCount].pv_score = -VALUE_INFINITE; else { // PV move or new best move! // Update PV ss->bestMove = move; - rml[i].pv_score = value; - rml[i].extract_pv_from_tt(pos); + rml[moveCount].pv_score = value; + rml[moveCount].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 (MultiPV == 1 && i > 0) + if (MultiPV == 1 && moveCount > 0) 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(i); + 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; @@ -875,7 +878,7 @@ namespace { alpha = value; } else // Set alpha equal to minimum score among the PV lines - alpha = rml[Min(i, MultiPV - 1)].pv_score; + alpha = rml[Min(moveCount, MultiPV - 1)].pv_score; } // PV move or new best move @@ -903,7 +906,7 @@ namespace { // Write PV lines to transposition table, in case the relevant entries // have been overwritten during the search. - for (int i = 0; i < MultiPV; i++) + for (int i = 0; i < Min(MultiPV, (int)rml.size()); i++) rml[i].insert_pv_in_tt(pos); return alpha; @@ -1927,12 +1930,21 @@ split_point_start: // At split points actual search starts from here } - // current_search_time() returns the number of milliseconds which have passed - // since the beginning of the current search. + // init_ss_array() does a fast reset of the first entries of a SearchStack + // array and of all the excludedMove and skipNullMove entries. - int current_search_time() { + void init_ss_array(SearchStack* ss, int size) { - return get_system_time() - SearchStartTime; + for (int i = 0; i < size; i++, ss++) + { + ss->excludedMove = MOVE_NONE; + ss->skipNullMove = false; + ss->reduction = DEPTH_ZERO; + ss->sp = NULL; + + if (i < 3) + ss->killers[0] = ss->killers[1] = ss->mateKiller = MOVE_NONE; + } } @@ -1955,7 +1967,17 @@ split_point_start: // At split points actual search starts from here return s.str(); } - // nps() computes the current nodes/second count. + + // current_search_time() returns the number of milliseconds which have passed + // since the beginning of the current search. + + int current_search_time() { + + return get_system_time() - SearchStartTime; + } + + + // nps() computes the current nodes/second count int nps(const Position& pos) { @@ -2042,31 +2064,13 @@ split_point_start: // At split points actual search starts from here bool noMoreTime = t > TimeMgr.maximum_time() || stillAtFirstMove; - if ( (Iteration >= 3 && UseTimeManagement && noMoreTime) + if ( (UseTimeManagement && noMoreTime) || (ExactMaxTime && t >= ExactMaxTime) - || (Iteration >= 3 && MaxNodes && pos.nodes_searched() >= MaxNodes)) + || (MaxNodes && pos.nodes_searched() >= MaxNodes)) // FIXME StopRequest = true; } - // init_ss_array() does a fast reset of the first entries of a SearchStack - // array and of all the excludedMove and skipNullMove entries. - - void init_ss_array(SearchStack* ss, int size) { - - for (int i = 0; i < size; i++, ss++) - { - ss->excludedMove = MOVE_NONE; - ss->skipNullMove = false; - ss->reduction = DEPTH_ZERO; - ss->sp = NULL; - - if (i < 3) - ss->killers[0] = ss->killers[1] = ss->mateKiller = MOVE_NONE; - } - } - - // wait_for_stop_or_ponderhit() is called when the maximum depth is reached // while the program is pondering. The point is to work around a wrinkle in // the UCI protocol: When pondering, the engine is not allowed to give a @@ -2080,6 +2084,7 @@ split_point_start: // At split points actual search starts from here while (true) { + // Wait for a command from stdin if (!std::getline(std::cin, command)) command = "quit";