Skip to content

Commit 88b35fa

Browse files
noobpwnftwclaude
andcommitted
Fix table lookup for equal-strength material configs
PieceConfig canonicalizes side ordering by total strength (stronger side -> White), but only swapped when bs > ws, leaving the bs == ws case with no tiebreak. For equal-strength asymmetric material (e.g. KQP vs KRR, both 1000), the canonical orientation then depended on which color held which pieces on the probed board, so cfg.name() produced "KQPKRR" or "KRRKQP" depending on the input. Since tables are opened by cfg.name(), half the orientations of every such material computed a filename that doesn't exist on disk and probing wrongly reported table-not-found. Add a deterministic tiebreak mirroring Piece_Config::sort_pieces in the C++ generator: when totals are equal, the side with more high-value pieces (more queens, then rooks, ...) becomes White, so cfg.name() reproduces the generator's on-disk filename. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 5f7ee3d commit 88b35fa

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

chess/chesstb.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,18 @@ def material_key_of(pieces: List[Tuple[int, int]]) -> int:
146146
_TYPE_ORDER = {KING: 0, QUEEN: 1, ROOK: 2, BISHOP: 3, KNIGHT: 4, PAWN: 5}
147147

148148

149+
def _composition_key(pieces: List[Tuple[int, int]], color: int) -> List[int]:
150+
"""Per-type piece counts for `color`, indexed by C++ type code so that
151+
lexicographic comparison orders by KING, QUEEN, ROOK, BISHOP, KNIGHT, PAWN.
152+
Mirrors the ``std::array<int8_t, PIECE_TYPE_NB>`` tiebreak key in
153+
``Piece_Config::sort_pieces`` (src/chess/piece_config.cpp)."""
154+
counts = [0] * (PAWN + 1)
155+
for c, t in pieces:
156+
if c == color:
157+
counts[t] += 1
158+
return counts
159+
160+
149161
class PieceConfig:
150162
"""Canonical material config. `pieces` is a list of (cpp_color, type)."""
151163

@@ -154,7 +166,10 @@ def __init__(self, pieces: List[Tuple[int, int]]):
154166
# Input may be in any orientation; we canonicalize.
155167
ws = sum(_STRENGTH[t] for c, t in pieces if c == CPP_WHITE)
156168
bs = sum(_STRENGTH[t] for c, t in pieces if c == CPP_BLACK)
157-
if bs > ws:
169+
swap = bs > ws
170+
if bs == ws:
171+
swap = _composition_key(pieces, CPP_BLACK) > _composition_key(pieces, CPP_WHITE)
172+
if swap:
158173
pieces = [(CPP_BLACK if c == CPP_WHITE else CPP_WHITE, t) for c, t in pieces]
159174
# sort: white side first then black; within side by type order.
160175
pieces = sorted(pieces, key=lambda ct: (ct[0], _TYPE_ORDER[ct[1]]))

0 commit comments

Comments
 (0)