Skip to content

Fix board corruption when an undo interrupts the practice-mode evaluation - #115

Closed
oers wants to merge 1 commit into
developmentfrom
claude/practice-abort-board-fix
Closed

oers wants to merge 1 commit into
developmentfrom
claude/practice-abort-board-fix

Conversation

@oers

@oers oers commented Sep 24, 2026

Copy link
Copy Markdown
Owner

This fixes the recurring WthorReplayTest failure "WThor game 155 undo of ply 28 (g8) did not clear that square". It has shown up on #96, #106, #112 and #114.

Cause

In practice mode, extended_compute_move (zebra/game.c) evaluates every legal move. For each candidate it makes the move, searches, and takes the move back. If the opponent has to pass after the candidate, it runs a second search for the same side.

An undo or redo interrupts the evaluation by setting force_return. The check after the first search took the move back before leaving the loop, but the check after the second search did not. So an undo that arrived during the second search left the candidate move on the board, and the position shown after the undo was wrong.

Game 155 after ply 28 is exactly that situation: White has to pass after most of Black's moves. That is why the failure always appeared there, and only when the timing hit the second search.

Fix

unmake_move is now also called before leaving on force_return after the second search, the same way as after the first search.

Test

New host test HostJniSmokeTest#undoDuringAPracticeEvaluationLeavesTheBoardIntact:

  • It loads game 155 up to ply 28 with practice mode on.
  • It undoes that ply 60 times, at varying points in the evaluation, and redoes it after each undo.
  • After each undo it compares the board with the known position after ply 27.

Results on the host (x86_64):

  • Without the fix, the test fails on the first attempt: a4: expected EMPTY, actual BLACK, …. The candidate a4 was left on the board.
  • With the fix, all 60 attempts pass, in three separate runs.
  • All 13 host JNI tests pass, including allWthorGamesUndoRedoRoundTripCleanly.

🤖 Generated with Claude Code

https://claude.ai/code/session_01V5G4cWSLBkiNNK4KC3zvXM


Generated by Claude Code

extended_compute_move (practice-mode evaluation) makes each candidate
move, searches, and unmakes it. If the opponent has to pass after the
candidate, it runs a second search for the same side. When an undo or
redo interrupted that second search (force_return), the loop left
without unmake_move, so the candidate stayed on the board and every
following undo/redo worked on a wrong position.

This is the WthorReplayTest flake "WThor game 155 undo of ply 28 (g8)
did not clear that square": after ply 28 White has to pass after most of
Black's moves, so an undo arriving during the evaluation often hit the
second search.

New host test undoDuringAPracticeEvaluationLeavesTheBoardIntact undoes
ply 28 of that game at varying points in the evaluation and compares
the board with the known position after ply 27. It failed on the first
attempt before this fix (a4 left on the board) and passes 60 of 60
attempts with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V5G4cWSLBkiNNK4KC3zvXM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants