X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Fsearch.cpp;h=f47507f7e39b6ad6ba7a7ffaf3ebe2f17e1cd6e0;hb=44a7db0f9ac02d2461aff39e25f1ac9107ffbfac;hp=214177a2afae1280eb296352fe59245dfd2c98cb;hpb=5451687efbb71e93a063a4d323cc9f73ba12e9a4;p=stockfish diff --git a/src/search.cpp b/src/search.cpp index 214177a2..f47507f7 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -297,7 +297,7 @@ void Thread::search() { mainThread->bestMoveChanges = 0; } - size_t multiPV = Options["MultiPV"]; + multiPV = Options["MultiPV"]; Skill skill(Options["Skill Level"]); // When playing with strength handicap enable MultiPV search that we will @@ -499,7 +499,7 @@ namespace { Key posKey; Move ttMove, move, excludedMove, bestMove; Depth extension, newDepth; - Value bestValue, value, ttValue, eval; + Value bestValue, value, ttValue, eval, maxValue; bool ttHit, inCheck, givesCheck, singularExtensionNode, improving; bool captureOrPromotion, doFullDepthSearch, moveCountPruning, skipQuiets, ttCapture, pvExact; Piece movedPiece; @@ -511,6 +511,7 @@ namespace { moveCount = captureCount = quietCount = ss->moveCount = 0; ss->statScore = 0; bestValue = -VALUE_INFINITE; + maxValue = VALUE_INFINITE; // Check for the available remaining time if (thisThread == Threads.main()) @@ -598,7 +599,7 @@ namespace { && !pos.can_castle(ANY_CASTLING)) { TB::ProbeState err; - TB::WDLScore v = Tablebases::probe_wdl(pos, &err); + TB::WDLScore wdl = Tablebases::probe_wdl(pos, &err); if (err != TB::ProbeState::FAIL) { @@ -606,15 +607,30 @@ namespace { int drawScore = TB::UseRule50 ? 1 : 0; - value = v < -drawScore ? -VALUE_MATE + MAX_PLY + ss->ply + 1 - : v > drawScore ? VALUE_MATE - MAX_PLY - ss->ply - 1 - : VALUE_DRAW + 2 * v * drawScore; + value = wdl < -drawScore ? -VALUE_MATE + MAX_PLY + ss->ply + 1 + : wdl > drawScore ? VALUE_MATE - MAX_PLY - ss->ply - 1 + : VALUE_DRAW + 2 * wdl * drawScore; - tte->save(posKey, value_to_tt(value, ss->ply), BOUND_EXACT, - std::min(DEPTH_MAX - ONE_PLY, depth + 6 * ONE_PLY), - MOVE_NONE, VALUE_NONE, TT.generation()); + Bound b = wdl < -drawScore ? BOUND_UPPER + : wdl > drawScore ? BOUND_LOWER : BOUND_EXACT; - return value; + if ( b == BOUND_EXACT + || (b == BOUND_LOWER ? value >= beta : value <= alpha)) + { + tte->save(posKey, value_to_tt(value, ss->ply), b, + std::min(DEPTH_MAX - ONE_PLY, depth + 6 * ONE_PLY), + MOVE_NONE, VALUE_NONE, TT.generation()); + + return value; + } + + if (PvNode) + { + if (b == BOUND_LOWER) + bestValue = value, alpha = std::max(alpha, bestValue); + else + maxValue = value; + } } } } @@ -786,12 +802,20 @@ moves_loop: // When in check search starts from here if (move == excludedMove) continue; - // At root obey the "searchmoves" option and skip moves not listed in Root - // Move List. As a consequence any illegal move is also skipped. In MultiPV - // mode we also skip PV moves which have been already searched. - if (rootNode && !std::count(thisThread->rootMoves.begin() + thisThread->PVIdx, - thisThread->rootMoves.end(), move)) - continue; + if (rootNode) + { + // At root obey the "searchmoves" option and skip moves not listed in Root + // Move List. As a consequence any illegal move is also skipped. + if (!std::count(thisThread->rootMoves.begin() + thisThread->PVIdx, + thisThread->rootMoves.end(), move)) + continue; + + // In MultiPV mode we not only skip PV moves which have already been searched, + // but also any other move except we have reached the last PV line. + if ( thisThread->PVIdx + 1 < thisThread->multiPV + && move != ttMove) + continue; + } ss->moveCount = ++moveCount; @@ -1091,6 +1115,9 @@ moves_loop: // When in check search starts from here && is_ok((ss-1)->currentMove)) update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth)); + if (PvNode) + bestValue = std::min(bestValue, maxValue); + if (!excludedMove) tte->save(posKey, value_to_tt(bestValue, ss->ply), bestValue >= beta ? BOUND_LOWER : @@ -1508,7 +1535,7 @@ string UCI::pv(const Position& pos, Depth depth, Value alpha, Value beta) { int elapsed = Time.elapsed() + 1; const RootMoves& rootMoves = pos.this_thread()->rootMoves; size_t PVIdx = pos.this_thread()->PVIdx; - size_t multiPV = std::min((size_t)Options["MultiPV"], rootMoves.size()); + size_t multiPV = pos.this_thread()->multiPV; uint64_t nodesSearched = Threads.nodes_searched(); uint64_t tbHits = Threads.tb_hits() + (TB::RootInTB ? rootMoves.size() : 0); @@ -1626,4 +1653,9 @@ void Tablebases::filter_root_moves(Position& pos, Search::RootMoves& rootMoves) TB::Score = TB::Score > VALUE_DRAW ? VALUE_MATE - MAX_PLY - 1 : TB::Score < VALUE_DRAW ? -VALUE_MATE + MAX_PLY + 1 : VALUE_DRAW; + + // Since root_probe() and root_probe_wdl() dirty the root move scores, + // we reset them to -VALUE_INFINITE + for (RootMove& rm : rootMoves) + rm.score = -VALUE_INFINITE; }