Add chess.chesstb: prober for chesstb endgame tablebases · niklasf/python-chess@661cc2e · GitHub
Skip to content

Commit 661cc2e

Browse files
noobpwnftwclaude
andcommitted
Add chess.chesstb: prober for chesstb endgame tablebases
chesstb tables store WDL, DTC, DTM and DTM50 for endgame material configurations. This adds a pure-Python reader for the format, shaped like chess.syzygy and chess.gaviota: open_tablebase() on a directory tree, then probe() a board for all four values at once, or probe_wdl / probe_dtc / probe_dtm / probe_dtm50 for one at a time. Conversion is probe_dtc rather than syzygy's probe_dtz: syzygy bases its cursed band off 100, so a DTZ magnitude carries the WDL class along with the count, while a DTC is a plain distance in every class. The format, as read here: one table per material configuration, split by side to move and compressed in blocks (LZMA, or LZ4 with an optional dictionary prefix). Positions are addressed by a combinatorial index over king symmetry classes and groups of identical pieces. Configurations of equal strength share a single table, read through a rank-mirrored, colour-swapped view of the position; one holding an opposing pawn pair may also ship a smaller frozen-pair ('p') table, which is preferred when present, and whose index counts only the free pieces. A table may omit one side to move altogether, in which case its values are recovered by minimaxing over legal children. En passant is not indexed and is applied as a virtual-capture overlay at probe time. DTM50 carries a prefix index every 256 positions within a block and layers its values by halfmove clock; its flat layer is also where DTM comes from, so the standalone DTM table -- a DTC table but for the value decode -- is read only for material shipping no pack. Tables are memory-mapped and decoded a block at a time, with a shared LRU holding decoded blocks across every open table against one budget. _TableFile._open_source is the single seam where the transport is decided, and the four table classes are named as class attributes, so serving tables from something other than a mapping is four subclasses and a _find. A Tablebase is safe to share between threads: probes register as readers so close() can wait for them before unmapping, and table opens are double-checked under a per-kind lock. Positions with castling rights are rejected with MissingTableError, as chess.syzygy and chess.gaviota do for the same input; the tables are built without them. Positions are assumed legal, as they are on the C++ side. Includes docs, tests, and seven small table sets (KBK..KRKR) as test data. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 8330cfd commit 661cc2e

33 files changed

Lines changed: 3853 additions & 0 deletions

‎README.rst‎

Lines changed: 19 additions & 0 deletions

0 commit comments

Comments
 (0)