diff options
| author | Scott Gasch <[email protected]> | 2026-09-16 08:27:00 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-09-16 08:27:00 -0700 |
| commit | 4a7ec9ac91939957fb3d3e5564fc24a385b422ff (patch) | |
| tree | 8cb4ff2bc95faadd559b89e0d23cade65eb405ec /src/eval.c | |
| parent | 966a0ef4da9cf3911eb3da0533179199808717b4 (diff) | |
Fix _RecognizeKPK misjudging a bishop-pawn stalemate-corner draw as a large win, and add exhaustive KPK/EGTB regression coverage to catch this class of bug going forward.
7k/8/5KP1/8/8/8/8/8 w - - (Kf6/Pg6/Kh8, White to move) was scored
+11.33 with PV=Kf7 -- Kf7 actually stalemates Black immediately; the
position is a draw with correct defense. Root cause:
_RecognizeKPK's critical-squares win check trusted a razor-thin
"strictly closer by any margin" king-race comparison, which Fine's
rule doesn't actually license once the approximate weak/strong tempo
adjustment above it is accounted for.
Two narrower, file-specific guards (bishop-pawn-only, one each in
recogn.c and eval.c's _EvalPasserRacesAgainstLoneKings) were tried
first based on the single known repro, then proven unnecessary and
removed once exhaustive testing showed the real fix: requiring the
strong king to be closer by 2+ tempi, not just 1, at the critical
square. Verified via a new TestRecognExhaustiveKPK (testrecogn.c,
on-demand, mirrors the existing TestRecognExhaustiveKNKP) against
EGTB ground truth: the old margin was wrong on 35 of 165,676
EGTB-covered legal single-pawn KPK positions (not just bishop-pawn
files -- rook pawns and even some central-file positions were also
affected); the new margin is wrong on zero.
Also added a small fixed-FEN regression list (g_rgRecognFenCases),
wired into the fast, always-run TestRecogn(), so this exact repro
(plus its b-file and color-flipped mirrors) is checked on every
engine startup rather than relying on the random fuzzer's luck --
confirmed the existing 150-iterations-per-case uniform random KPK
fuzz test essentially never lands on this class of narrow
corner/stalemate configuration.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 17 |
1 files changed, 16 insertions, 1 deletions
@@ -4876,7 +4876,21 @@ Routine description: Determine if one side has a pawn that is unstoppable. - This is broken for positions like: + A 2026-09-16 investigation (see recogn.c's _RecognizeKPK for the + full writeup) found this function's own king-catches-pawn race + distance comparison did NOT actually reproduce the bug in + 7k/8/5KP1/8/8/8/8/8 w - - (Kf6/Pg6/Kh8, White to move -- a draw + via stalemate defense that a sibling function, _RecognizeKPK, used + to misjudge as a win) -- a file-specific guard added here on + suspicion turned out to be unnecessary once _RecognizeKPK's real + bug was fixed and was removed after TestRecognExhaustiveKPK + (testrecogn.c) confirmed 0 wrong verdicts across all EGTB-covered + legal KPK positions without it. Left undocumented/unfixed here: + whether this function has its own independent bugs of the same + general shape was NOT exhaustively verified (TestRecognExhaustiveKPK + exercises it only via RecognLookup's pHash-lookup call path, which + doesn't reach every branch of this function directly) -- worth + exhaustively checking on its own if this area gets touched again. Parameters: @@ -4943,6 +4957,7 @@ Return value: cQueen = FILE_RANK_TO_COOR(FILE(c), QUEENING_RANK[uColor]); ASSERT(FILE(cQueen) == FILE(c)); + uPawnDist = RANK_DISTANCE(cQueen, c); if ((RANK(c) == JUMPING_RANK[uColor]) && (IS_EMPTY(pos->rgSquare[c + d1].pPiece) && |
