Add transposition table, iterative deepening, and repetition-aware search

- Refactor the search to negamax (single side-relative score + alpha/beta window)
- Add a shared, process-wide transposition table: lock-free XOR-verified slots,
  persists across games, with depth-gated and difficulty-capped score reuse so a
  weak bot can't borrow a stronger game's deeper analysis
- Drive the search with iterative deepening, seeding each depth's move ordering
  from the previous one
- Seed prior-position history (Position::seed_history) over a new engine_best_move
  history parameter so the engine detects threefold/50-move draws the FEN can't carry

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
Josh-Heaps
2026-06-08 18:58:59 -06:00
co-authored by Claude Opus 4.8
parent 76b054ee9d
commit 5345427e0c
4 changed files with 239 additions and 54 deletions
@@ -57,6 +57,10 @@ CHESS_API int CHESS_CALL engine_set_option(EngineHandle engine,
/* Compute the best move for the given position.
* engine : handle from engine_create.
* fen : null-terminated UTF-8 FEN of the position to move from.
* history : optional null-terminated UTF-8 list of the prior positions since the
* last irreversible move (capture/pawn move), one FEN per line, oldest
* first, NOT including `fen`. Lets the engine detect threefold/50-move
* draws that the FEN alone can't carry. May be NULL or empty.
* out_buf : host-owned buffer the engine writes the UCI move into,
* as a null-terminated ASCII string (e.g. "e2e4\0").
* out_len : capacity of out_buf in bytes (host passes >= 8).
@@ -64,6 +68,7 @@ CHESS_API int CHESS_CALL engine_set_option(EngineHandle engine,
* MUST NOT write more than out_len bytes including the NUL terminator. */
CHESS_API int CHESS_CALL engine_best_move(EngineHandle engine,
const char* fen,
const char* history,
char* out_buf,
int out_len);