X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=ec884b3c145afc20dbcdff887e056ba671552827;hp=0e65d19ff3c9f5d8da2d9fd7887ceb2bb42ec3e5;hb=80f5ca88f6eaead0c5460c4bc13c1c7d9477c2be;hpb=94bb1964f6b5b4b9abca0bde03367d071922f449 diff --git a/src/search.cpp b/src/search.cpp index 0e65d19f..ec884b3c 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -257,7 +257,7 @@ namespace { int SearchStartTime, MaxNodes, MaxDepth, MaxSearchTime; int AbsoluteMaxSearchTime, ExtraSearchTime, ExactMaxTime; bool UseTimeManagement, InfiniteSearch, PonderSearch, StopOnPonderhit; - bool FirstRootMove, AbortSearch, Quit, AspirationFailLow, ZugDetection; + bool FirstRootMove, AbortSearch, Quit, AspirationFailLow; // Log file bool UseLogFile; @@ -294,7 +294,7 @@ namespace { Depth extension(const Position&, Move, bool, bool, bool, bool, bool, bool*); bool ok_to_do_nullmove(const Position& pos); bool ok_to_prune(const Position& pos, Move m, Move threat); - bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply, bool allowNullmove); + bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply); Value refine_eval(const TTEntry* tte, Value defaultEval, int ply); void update_history(const Position& pos, Move move, Depth depth, Move movesSearched[], int moveCount); void update_killers(Move m, SearchStack& ss); @@ -425,7 +425,6 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move, MultiPV = get_option_value_int("MultiPV"); Chess960 = get_option_value_bool("UCI_Chess960"); UseLogFile = get_option_value_bool("Use Search Log"); - ZugDetection = get_option_value_bool("Zugzwang detection"); // To be removed after 1.7.1 if (UseLogFile) LogFile.open(get_option_value_string("Search Log Filename").c_str(), std::ios::out | std::ios::app); @@ -561,7 +560,7 @@ void init_search() { for (int j = 0; j < 64; j++) // j == moveNumber { // FIXME: test using log instead of BSR - FutilityMarginsMatrix[i][j] = (i < 2 ? 0 : 112 * bitScanReverse32(i * i / 2)) - 8 * j; + FutilityMarginsMatrix[i][j] = (i < 2 ? 0 : 112 * bitScanReverse32(i * i / 2)) - 8 * j + 45; } // Init futility move count array @@ -1300,8 +1299,11 @@ namespace { tte = TT.retrieve(posKey); ttMove = (tte ? tte->move() : MOVE_NONE); - if (tte && ok_to_use_TT(tte, depth, beta, ply, allowNullmove)) + if (tte && ok_to_use_TT(tte, depth, beta, ply)) { + // Refresh tte entry to avoid aging + TT.store(posKey, tte->value(), tte->type(), tte->depth(), ttMove); + ss[ply].currentMove = ttMove; // Can be MOVE_NONE return value_from_tt(tte->value(), ply); } @@ -1380,18 +1382,13 @@ namespace { if (nullValue >= value_mate_in(PLY_MAX)) nullValue = beta; - // Do zugzwang verification search for high depths, don't store in TT - // if search was stopped. - if ( ( depth < 6 * OnePly - || search(pos, ss, beta, depth-5*OnePly, ply, false, threadID) >= beta) - && !AbortSearch - && !TM.thread_should_stop(threadID)) - { - assert(value_to_tt(nullValue, ply) == nullValue); + if (depth < 6 * OnePly) + return nullValue; - TT.store(posKey, nullValue, VALUE_TYPE_NS_LO, depth, MOVE_NONE); + // Do zugzwang verification search + Value v = search(pos, ss, beta, depth-5*OnePly, ply, false, threadID); + if (v >= beta) return nullValue; - } } else { // The null move failed low, which means that we may be faced with // some kind of threat. If the previous move was reduced, check if @@ -1486,7 +1483,7 @@ namespace { // Value based pruning Depth predictedDepth = newDepth - nonpv_reduction(depth, moveCount); // We illogically ignore reduction condition depth >= 3*OnePly futilityValueScaled = ss[ply].eval + futility_margin(predictedDepth, moveCount) - + H.gain(pos.piece_on(move_from(move)), move_to(move)) + 45; + + H.gain(pos.piece_on(move_from(move)), move_to(move)); if (futilityValueScaled < beta) { @@ -1626,7 +1623,7 @@ namespace { tte = TT.retrieve(pos.get_key()); ttMove = (tte ? tte->move() : MOVE_NONE); - if (!pvNode && tte && ok_to_use_TT(tte, depth, beta, ply, true)) + if (!pvNode && tte && ok_to_use_TT(tte, depth, beta, ply)) { assert(tte->type() != VALUE_TYPE_EVAL); @@ -1844,7 +1841,7 @@ namespace { // Value based pruning Depth predictedDepth = newDepth - nonpv_reduction(sp->depth, moveCount); futilityValueScaled = ss[sp->ply].eval + futility_margin(predictedDepth, moveCount) - + H.gain(pos.piece_on(move_from(move)), move_to(move)) + 45; + + H.gain(pos.piece_on(move_from(move)), move_to(move)); if (futilityValueScaled < sp->beta) { @@ -2307,18 +2304,14 @@ namespace { } - // ok_to_use_TT() returns true if a transposition table score can be used at a - // given point in search. To avoid zugzwang issues TT cutoffs at the root node - // of a null move verification search are not allowed if the TT value was found - // by a null search, this is implemented testing allowNullmove and TT entry type. + // ok_to_use_TT() returns true if a transposition table score + // can be used at a given point in search. - bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply, bool allowNullmove) { + bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply) { Value v = value_from_tt(tte->value(), ply); - return (allowNullmove || !(tte->type() & VALUE_TYPE_NULL) || !ZugDetection) - - && ( tte->depth() >= depth + return ( tte->depth() >= depth || v >= Max(value_mate_in(PLY_MAX), beta) || v < Min(value_mated_in(PLY_MAX), beta))