X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=022f3a9d15b8a08a5c78483490156051e4f732d7;hp=0e3838371fe0bc95366462fd1b8d547a2e3bd079;hb=6a8e46d53efca6dd56a396b32f43bef9f95127d6;hpb=a9e55d43262d11a916bdfa68cd1de0174d884cd3 diff --git a/src/search.cpp b/src/search.cpp index 0e383837..022f3a9d 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -121,6 +121,9 @@ namespace { // Depth limit for selective search: Depth SelectiveDepth = 7*OnePly; + // Use dynamic LMR? + const bool UseDynamicLMR = false; + // Use internal iterative deepening? const bool UseIIDAtPVNodes = true; const bool UseIIDAtNonPVNodes = false; @@ -1333,7 +1336,9 @@ namespace { && !move_is_killer(move, ss[ply])) { // LMR dynamic reduction - Depth R = (moveCount >= 2 * LMRNonPVMoves && depth > 7*OnePly ? 2*OnePly : OnePly); + Depth R = UseDynamicLMR + && moveCount >= 2 * LMRNonPVMoves + && depth > 7*OnePly ? 2*OnePly : OnePly; ss[ply].reduction = R; value = -search(pos, ss, -(beta-1), newDepth-R, ply+1, true, threadID); @@ -1429,18 +1434,38 @@ namespace { return VALUE_DRAW; // Transposition table lookup, only when not in PV + TTEntry* tte = NULL; bool pvNode = (beta - alpha != 1); if (!pvNode) { - const TTEntry* tte = TT.retrieve(pos); + tte = TT.retrieve(pos); if (tte && ok_to_use_TT(tte, depth, beta, ply)) + { + assert(tte->type() != VALUE_TYPE_EVAL); + return value_from_tt(tte->value(), ply); + } } // Evaluate the position statically EvalInfo ei; + Value staticValue; bool isCheck = pos.is_check(); - Value staticValue = (isCheck ? -VALUE_INFINITE : evaluate(pos, ei, threadID)); + + if (isCheck) + staticValue = -VALUE_INFINITE; + + else if (tte && (tte->type() == VALUE_TYPE_EVAL || tte->staticValue())) + { + // Use the cached evaluation score if possible + assert(tte->value() == evaluate(pos, ei, threadID)); + assert(ei.futilityMargin == Value(0)); + + staticValue = tte->value(); + ei.futilityMargin = Value(0); // manually initialize futilityMargin + } + else + staticValue = evaluate(pos, ei, threadID); if (ply == PLY_MAX - 1) return evaluate(pos, ei, threadID); @@ -1450,7 +1475,13 @@ namespace { Value bestValue = staticValue; if (bestValue >= beta) + { + // Store the score to avoid a future costly evaluation() call + if (!isCheck && !tte && ei.futilityMargin == 0) + TT.store(pos, value_to_tt(bestValue, ply), Depth(-127*OnePly), MOVE_NONE, VALUE_TYPE_EVAL); + return bestValue; + } if (bestValue > alpha) alpha = bestValue; @@ -1458,7 +1489,7 @@ namespace { // Initialize a MovePicker object for the current position, and prepare // to search the moves. Because the depth is <= 0 here, only captures, // queen promotions and checks (only if depth == 0) will be generated. - MovePicker mp = MovePicker(pos, pvNode, MOVE_NONE, EmptySearchStack, depth, isCheck ? NULL : &ei); + MovePicker mp = MovePicker(pos, pvNode, MOVE_NONE, EmptySearchStack, depth); Move move; int moveCount = 0; Bitboard dcCandidates = mp.discovered_check_candidates(); @@ -1535,7 +1566,25 @@ namespace { assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE); // Update transposition table - TT.store(pos, value_to_tt(bestValue, ply), depth, MOVE_NONE, VALUE_TYPE_EXACT); + if (!pvNode) + { + Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1)); + Value v = value_to_tt(bestValue, ply); + TTEntry* e; + if (bestValue < beta) + e = TT.store(pos, v, d, MOVE_NONE, VALUE_TYPE_UPPER); + else + e = TT.store(pos, v, d, MOVE_NONE, VALUE_TYPE_LOWER); + + assert(e && e == TT.retrieve(pos)); + assert(!e->staticValue()); + + // If the just stored value happens to be equal to the static evaluation + // score then set the flag, so to avoid calling evaluation() next time we + // hit this position. + if (staticValue == v && !ei.futilityMargin) + e->setStaticValue(); + } // Update killers only for good check moves Move m = ss[ply].currentMove; @@ -2412,7 +2461,7 @@ namespace { || ( !FailHigh && !fail_high_ply_1() && !Problem && t > 6*(MaxSearchTime + ExtraSearchTime)); - if ( (Iteration >= 2 && (!InfiniteSearch && overTime)) + if ( (Iteration >= 3 && (!InfiniteSearch && overTime)) || (ExactMaxTime && t >= ExactMaxTime) || (Iteration >= 3 && MaxNodes && nodes_searched() >= MaxNodes)) AbortSearch = true; @@ -2426,7 +2475,7 @@ namespace { void ponderhit() { int t = current_search_time(); PonderSearch = false; - if(Iteration >= 2 && + if(Iteration >= 3 && (!InfiniteSearch && (StopOnPonderhit || t > AbsoluteMaxSearchTime || (RootMoveNumber == 1 &&