moveCount = captureCount = quietCount = ss->moveCount = 0;
bestValue = -VALUE_INFINITE;
maxValue = VALUE_INFINITE;
+ ss->distanceFromPv = (PvNode ? 0 : ss->distanceFromPv);
// Check for the available remaining time
if (thisThread == Threads.main())
// Step 15. Make the move
pos.do_move(move, st, givesCheck);
- // Step 16. Reduced depth search (LMR, ~200 Elo). If the move fails high it will be
- // re-searched at full depth.
+ (ss+1)->distanceFromPv = ss->distanceFromPv + moveCount - 1;
+
+ // Step 16. Late moves reduction / extension (LMR, ~200 Elo)
+ // We use various heuristics for the sons of a node after the first son has
+ // been searched. In general we would like to reduce them, but there are many
+ // cases where we extend a son if it has good chances to be "interesting".
if ( depth >= 3
&& moveCount > 1 + 2 * rootNode
&& ( !captureOrPromotion
r++;
// Decrease/increase reduction for moves with a good/bad history (~30 Elo)
- // If we are not in check use statScore, if we are in check
- // use sum of main history and first continuation history with an offset
+ // If we are not in check use statScore, but if we are in check we use
+ // the sum of main history and first continuation history with an offset.
if (ss->inCheck)
r -= (thisThread->mainHistory[us][from_to(move)]
+ (*contHist[0])[movedPiece][to_sq(move)] - 3833) / 16384;
r -= ss->statScore / 14790;
}
- Depth d = std::clamp(newDepth - r, 1, newDepth);
+ // In general we want to cap the LMR depth search at newDepth. But for nodes
+ // close to the principal variation the cap is at (newDepth + 1), which will
+ // allow these nodes to be searched deeper than the pv (up to 4 plies deeper).
+ Depth d = std::clamp(newDepth - r, 1, newDepth + ((ss+1)->distanceFromPv <= 4));
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, true);
- doFullDepthSearch = value > alpha && d != newDepth;
-
+ // If the son is reduced and fails high it will be re-searched at full depth
+ doFullDepthSearch = value > alpha && d < newDepth;
didLMR = true;
}
else
{
doFullDepthSearch = !PvNode || moveCount > 1;
-
didLMR = false;
}