From b366c7dc38145278a00c51a560a4f7b6e03a0b2a Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Mon, 31 Jan 2011 13:05:01 +0100 Subject: [PATCH] Use TT for pruning also in PV nodes Biggest advantage is be able to analize positions without "loss of memory" when goind back/forth in a position. Patch has proven to fix analysys problems and is even worths some elo points. After 5811 games Mod- Orig: 1037 - 902 - 3872 +8 ELO (+- 3.6) LOS 97% Signed-off-by: Marco Costalba --- src/search.cpp | 28 +++++++++++++++++++--------- src/tt.cpp | 2 +- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index eb19b51d..791cbc6f 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -297,6 +297,7 @@ namespace { Value value_to_tt(Value v, int ply); Value value_from_tt(Value v, int ply); bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply); + bool ok_to_use_TT_PV(const TTEntry* tte, Depth depth, Value alpha, Value beta, int ply); bool connected_threat(const Position& pos, Move m, Move threat); Value refine_eval(const TTEntry* tte, Value defaultEval, int ply); void update_history(const Position& pos, Move move, Depth depth, Move movesSearched[], int moveCount); @@ -838,14 +839,10 @@ namespace { tte = TT.retrieve(posKey); ttMove = tte ? tte->move() : MOVE_NONE; - // At PV nodes, we don't use the TT for pruning, but only for move ordering. - // This is to avoid problems in the following areas: - // - // * Repetition draw detection - // * Fifty move rule detection - // * Searching for a mate - // * Printing of full PV line - if (!PvNode && tte && ok_to_use_TT(tte, depth, beta, ply)) + // At PV nodes we check for exact scores within (alha, beta) range, while + // at non-PV nodes we check for and return a fail high/low. Biggest advantage + // at probing at PV nodes is to have a smooth experience in analysis mode. + if (!Root && tte && (PvNode ? ok_to_use_TT_PV(tte, depth, alpha, beta, ply) : ok_to_use_TT(tte, depth, beta, ply))) { TT.refresh(tte); ss->bestMove = ttMove; // Can be MOVE_NONE @@ -1797,7 +1794,9 @@ split_point_start: // At split points actual search starts from here // ok_to_use_TT() returns true if a transposition table score - // can be used at a given point in search. + // can be used at a given point in search. There are two versions + // one to be used in non-PV nodes and one in PV nodes where we look + // for an exact score that falls between (alha, beta) boundaries. bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply) { @@ -1811,6 +1810,17 @@ split_point_start: // At split points actual search starts from here || ((tte->type() & VALUE_TYPE_UPPER) && v < beta)); } + bool ok_to_use_TT_PV(const TTEntry* tte, Depth depth, Value alpha, Value beta, int ply) { + + Value v = value_from_tt(tte->value(), ply); + + return tte->depth() >= depth + && tte->type() == VALUE_TYPE_EXACT + && tte->move() != MOVE_NONE + && v < beta + && v > alpha; + } + // refine_eval() returns the transposition table score if // possible otherwise falls back on static position evaluation. diff --git a/src/tt.cpp b/src/tt.cpp index 20ac1608..773f03cc 100644 --- a/src/tt.cpp +++ b/src/tt.cpp @@ -122,7 +122,7 @@ void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d, continue; c1 = (replace->generation() == generation ? 2 : 0); - c2 = (tte->generation() == generation ? -2 : 0); + c2 = (tte->generation() == generation || tte->type() == VALUE_TYPE_EXACT ? -2 : 0); c3 = (tte->depth() < replace->depth() ? 1 : 0); if (c1 + c2 + c3 > 0) -- 2.39.2