X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=434587a87d5c6e40c627ca3a54edfbad779a1f0d;hp=72530f2e94a1a324ef0c5818a2677c0aed5d543b;hb=659c54582ddb1bbbf80f7022a80c027ab0bd4c42;hpb=db46602b1ff41ff5ef1c41ed04829dc964722b25 diff --git a/src/search.cpp b/src/search.cpp index 72530f2e..434587a8 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) + { + // 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,14 @@ 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)); + if (bestValue < beta) + TT.store(pos, value_to_tt(bestValue, ply), d, MOVE_NONE, VALUE_TYPE_UPPER); + else + TT.store(pos, value_to_tt(bestValue, ply), d, MOVE_NONE, VALUE_TYPE_LOWER); + } // Update killers only for good check moves Move m = ss[ply].currentMove;