diff options
| author | Scott Gasch <[email protected]> | 2026-09-15 23:17:33 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-09-15 23:17:33 -0700 |
| commit | c0ac3d7845f60c7f6f2c3bfc306ceb0e4ac045ba (patch) | |
| tree | e2b7427e212bd5b557f15131b815517a86b20486 /src/search.c | |
| parent | 0bb4ae3052cb8ff9ffcf951b3ef0e6f50a7efdfa (diff) | |
Rework check/pawn-push/recapture extension gating on real SEE (GetMoveSee, generalized from GetCheckSee), restrict LMR to leftover moves only, and tighten recapture's window back to 1x after measuring a 6.8x node blowup from sharing the wider window.
Head-to-head match at 1170 games confirms parity with the prior head (score=0.510, LLR still between bounds) -- landing as a neutral-or-better baseline rather than a regression.
Diffstat (limited to 'src/search.c')
| -rw-r--r-- | src/search.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/src/search.c b/src/search.c index 4e89a2c..573f78c 100644 --- a/src/search.c +++ b/src/search.c @@ -189,7 +189,7 @@ Search(IN SEARCHER_THREAD_CONTEXT *ctx, ULONG uFutilityMargin = 0; FLAG fAnyMoveEFPPruned = FALSE; FLAG fThisMoveEFPPruned = FALSE; - SCORE iCheckSee; + SCORE iMoveSee; #ifdef DEBUG ASSERT(IS_VALID_SCORE(iAlpha)); ASSERT(IS_VALID_SCORE(iBeta)); @@ -745,14 +745,22 @@ Search(IN SEARCHER_THREAD_CONTEXT *ctx, #endif // SEE must be computed on the PRE-move position -- see.c's - // exchange walk needs the piece still sitting on cFrom. Only - // needed for checking moves, where ComputeMoveExtension uses it - // to gate the check extension on soundness (Crafty-style: don't - // extend a checking move that's really just a losing sacrifice). - iCheckSee = 0; - if (IS_CHECKING_MOVE(mv)) + // exchange walk needs the piece still sitting on cFrom. + // ComputeMoveExtension uses it for two soundness gates: the + // check extension (Crafty-style: don't extend a checking move + // that's really just a losing sacrifice) and the recapture + // extension (don't extend a "recapture" that actually loses + // material). uDepth <= THREE_PLY mirrors the recapture + // extension's own depth gate -- cheap to test here since + // uDepth is already loop-invariant, and it keeps this from + // computing a SEE on every single non-pawn capture at every + // depth. One call per move regardless of which gate(s) end up + // wanting it -- SEE is too hot a routine to pay for twice. + iMoveSee = 0; + if (IS_CHECKING_MOVE(mv) || + (mv.pCaptured && !IS_PAWN(mv.pCaptured) && (uDepth <= THREE_PLY))) { - iCheckSee = GetCheckSee(ctx, + iMoveSee = GetMoveSee(ctx, mv, (uStage == TRY_GENERATED_MOVES) ? (x - 1) : (ULONG)-1); @@ -773,7 +781,8 @@ Search(IN SEARCHER_THREAD_CONTEXT *ctx, (x - 1), // Note: x==0 if doing mvHash iEval, uDepth, - iCheckSee, + iMoveSee, + fIsLeftoverMove, &iExtend); // Note: MAX_EXTEND_PER_LINE (a flat, non-depth-relative cap on @@ -786,8 +795,9 @@ Search(IN SEARCHER_THREAD_CONTEXT *ctx, // Decide how much (if any) to reduce this move's depth -- // graded LMR. if ((uDepth > TWO_PLY) && - (NODE_PV != pi->eNodeType) && + (pi->eNodeType != NODE_PV) && (uLegalMoves > 5) && + (fIsLeftoverMove) && (0 == iExtend) && (!IS_ESCAPING_CHECK(mv)) && (!IS_CAPTURE_OR_PROMOTION(mv)) && @@ -1570,7 +1580,7 @@ _ShouldWeConsiderThisMove(IN SEARCHER_THREAD_CONTEXT *ctx, // a real (winning/even) iMoveValue gets the same value-plus- // flat-bonus treatment as any other capture; a move with no // usable value (SEE already called it losing) falls back to - // GetCheckSee's real tactical judgment, exactly like the + // GetMoveSee's real tactical judgment, exactly like the // quiet-check (VALUE_BISHOP) branch already does below. if (IS_CHECKING_MOVE(mv) && (TRUE == fGeneratedChecks)) { @@ -1590,7 +1600,7 @@ _ShouldWeConsiderThisMove(IN SEARCHER_THREAD_CONTEXT *ctx, return(fConsider); } { - FLAG fConsider = (GetCheckSee(ctx, mv, uMoveNum) >= 0); + FLAG fConsider = (GetMoveSee(ctx, mv, uMoveNum) >= 0); #ifdef CALIBRATE_QSEARCH_FUTILITY if (FALSE == fConsider) { @@ -1640,7 +1650,7 @@ _ShouldWeConsiderThisMove(IN SEARCHER_THREAD_CONTEXT *ctx, return(TRUE); } { - FLAG fConsider = (GetCheckSee(ctx, mv, uMoveNum) >= 0); + FLAG fConsider = (GetMoveSee(ctx, mv, uMoveNum) >= 0); #ifdef CALIBRATE_QSEARCH_FUTILITY if (FALSE == fConsider) { |
