summaryrefslogtreecommitdiff
path: root/src/eval.c
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-09-16 08:27:00 -0700
committerScott Gasch <[email protected]>2026-09-16 08:27:00 -0700
commit4a7ec9ac91939957fb3d3e5564fc24a385b422ff (patch)
tree8cb4ff2bc95faadd559b89e0d23cade65eb405ec /src/eval.c
parent966a0ef4da9cf3911eb3da0533179199808717b4 (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.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/eval.c b/src/eval.c
index 6764349..730365e 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -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) &&