From fd4d800c9842ee5b6bf99fa6d06707e678eb14fe Mon Sep 17 00:00:00 2001 From: syzygy1 <3028851+syzygy1@users.noreply.github.com> Date: Sun, 28 Jan 2018 14:40:07 +0100 Subject: [PATCH] This modifies the in-search TB probing to continue searching for a mate "behind" a TB win (or loss). (#1285) It does the following: - If a TB win or loss value allows an alpha or beta cutoff, the cutoff is taken. - Otherwise, the search of the current subtree continues. In PV nodes, the final value returned is adjusted to reflect that the position is a TB win (or loss). The patch also fixes a potential problem caused by root_probe() and root_probe_wdl() dirtying the root-move scores. This patch removes the limitation of current master that a mate is never found if the root position is not yet in the TBs, but the path to mate at some point enters the TBs. The patch is intended to preserve the efficiency and effectiveness of the current TB probing approach. No functional change (withouth TB) --- src/search.cpp | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 214177a2..b9ce9a62 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -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; + } } } } @@ -1091,6 +1107,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 : @@ -1626,4 +1645,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; } -- 2.39.2