X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=22d5d647447d520accc4c23ec785766e6abfde0b;hp=37c3bd71bb40e2aab91f4e45751684b0e86d7ebb;hb=35e39a196d0d0bc135a5e6acbfbb6130c832e004;hpb=b4870595a5652f7a5ecf577e33d0302b725b7f51 diff --git a/src/search.cpp b/src/search.cpp index 37c3bd71..22d5d647 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -179,8 +179,7 @@ namespace { // Step 9. Internal iterative deepening // Minimum depth for use of internal iterative deepening - const Depth IIDDepthAtPVNodes = 5 * OnePly; - const Depth IIDDepthAtNonPVNodes = 8 * OnePly; + const Depth IIDDepth[2] = { 8 * OnePly /* non-PV */, 5 * OnePly /* PV */}; // At Non-PV nodes we do an internal iterative deepening search // when the static evaluation is at most IIDMargin below beta. @@ -1023,11 +1022,11 @@ namespace { } - // search_pv() is the main search function for PV nodes. + // search<>() is the main search function for both PV and non-PV nodes template - Value search(Position& pos, SearchStack ss[], Value alpha, Value beta, - Depth depth, int ply, bool allowNullmove, int threadID, Move excludedMove) { + Value search(Position& pos, SearchStack ss[], Value alpha, Value beta, Depth depth, + int ply, bool allowNullmove, int threadID, Move excludedMove) { assert(alpha >= -VALUE_INFINITE && alpha <= VALUE_INFINITE); assert(beta > alpha && beta <= VALUE_INFINITE); @@ -1099,7 +1098,7 @@ namespace { isCheck = pos.is_check(); if (!isCheck) { - if (!PvNode && tte && (tte->type() & VALUE_TYPE_EVAL)) + if (tte && (tte->type() & VALUE_TYPE_EVAL)) ss[ply].eval = value_from_tt(tte->value(), ply); else ss[ply].eval = evaluate(pos, ei, threadID); @@ -1197,23 +1196,12 @@ namespace { } // Step 9. Internal iterative deepening - // We have different rules for PV nodes and non-pv nodes - if ( PvNode - && depth >= IIDDepthAtPVNodes - && ttMove == MOVE_NONE) - { - search(pos, ss, alpha, beta, depth-2*OnePly, ply, false, threadID); - ttMove = ss[ply].pv[ply]; - tte = TT.retrieve(posKey); - } - - if ( !PvNode - && depth >= IIDDepthAtNonPVNodes + if ( depth >= IIDDepth[PvNode] && ttMove == MOVE_NONE - && !isCheck - && ss[ply].eval >= beta - IIDMargin) + && (PvNode || (!isCheck && ss[ply].eval >= beta - IIDMargin))) { - search(pos, ss, alpha, beta, depth/2, ply, false, threadID); + Depth d = (PvNode ? depth - 2 * OnePly : depth / 2); + search(pos, ss, alpha, beta, d, ply, false, threadID); ttMove = ss[ply].pv[ply]; tte = TT.retrieve(posKey); } @@ -1259,9 +1247,10 @@ namespace { if (abs(ttValue) < VALUE_KNOWN_WIN) { - Value excValue = search(pos, ss, ttValue - SingularExtensionMargin - 1, ttValue - SingularExtensionMargin, depth / 2, ply, false, threadID, move); + Value b = ttValue - SingularExtensionMargin; + Value v = search(pos, ss, b - 1, b, depth / 2, ply, false, threadID, move); - if (excValue < ttValue - SingularExtensionMargin) + if (v < ttValue - SingularExtensionMargin) ext = OnePly; } } @@ -1286,7 +1275,7 @@ namespace { continue; // Value based pruning - Depth predictedDepth = newDepth - reduction(depth, moveCount); // We illogically ignore reduction condition depth >= 3*OnePly + Depth predictedDepth = newDepth - reduction(depth, moveCount); // FIXME 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)); @@ -1307,34 +1296,36 @@ namespace { value = -search(pos, ss, -beta, -alpha, newDepth, ply+1, false, threadID); else { - // Step 14. Reduced search - // if the move fails high will be re-searched at full depth. - bool doFullDepthSearch = true; - - if ( depth >= 3 * OnePly - && !dangerous - && !captureOrPromotion - && !move_is_castle(move) - && !move_is_killer(move, ss[ply])) - { - ss[ply].reduction = reduction(depth, moveCount); - if (ss[ply].reduction) - { - value = -search(pos, ss, -(alpha+1), -alpha, newDepth-ss[ply].reduction, ply+1, true, threadID); - doFullDepthSearch = (value > alpha); - } - } - - // Step 15. Full depth search - if (doFullDepthSearch) - { - ss[ply].reduction = Depth(0); - value = -search(pos, ss, -(alpha+1), -alpha, newDepth, ply+1, true, threadID); + // Step 14. Reduced search + // if the move fails high will be re-searched at full depth. + bool doFullDepthSearch = true; + + if ( depth >= 3 * OnePly + && !dangerous + && !captureOrPromotion + && !move_is_castle(move) + && !move_is_killer(move, ss[ply])) + { + ss[ply].reduction = reduction(depth, moveCount); + if (ss[ply].reduction) + { + value = -search(pos, ss, -(alpha+1), -alpha, newDepth-ss[ply].reduction, ply+1, true, threadID); + doFullDepthSearch = (value > alpha); + } + } - // Step extra. pv search (only in PV nodes) - if (PvNode && value > alpha && value < beta) - value = -search(pos, ss, -beta, -alpha, newDepth, ply+1, false, threadID); - } + // Step 15. Full depth search + if (doFullDepthSearch) + { + ss[ply].reduction = Depth(0); + value = -search(pos, ss, -(alpha+1), -alpha, newDepth, ply+1, true, threadID); + + // Step extra. pv search (only in PV nodes) + // Search only for possible new PV nodes, if instead value >= beta then + // parent node fails low with value <= alpha and tries another move. + if (PvNode && value > alpha && value < beta) + value = -search(pos, ss, -beta, -alpha, newDepth, ply+1, false, threadID); + } } // Step 16. Undo move