Skip to content

fix: resolve GNU bear-off die ambiguity to the larger die#45

Merged
nodots merged 1 commit into
mainfrom
fix/matcher-prefer-larger-die
Jun 7, 2026
Merged

fix: resolve GNU bear-off die ambiguity to the larger die#45
nodots merged 1 commit into
mainfrom
fix/matcher-prefer-larger-die

Conversation

@nodots

@nodots nodots commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Problem

Production game 2d98cf14-e262-433c-baf5-95a2f878311d froze in moving on the final play: robot with one checker on its 2-point, 14 off, roll [3,5]. GNU's bearoff hint is a single step {from: 2, to: 0} with no die value. The matcher compares bear-off steps on origin position only, so both ready moves matched and the first in roll order won — die 3. Core's must-use-larger-die rule (core PR nodots/backgammon-core#129) rejected the turn with MustUseLargerDieError on every retry; RobotActionProcessor swallows robot-turn errors, so the game was never persisted.

Reproduced locally by running executeRobotTurnWithGNU against the prod game JSON — threw Must use the larger die (5) when only one die can be played; 3 was used.

Fix

Sort ready moves by die value descending before matching. Point-to-point and reenter matching is die-unique (origin+destination determine the die), so the sort only affects the ambiguous bear-off case — where the larger die is always safe, and mandatory when it ends the turn. Also heals pre-fix plays persisted with both moves still ready (the stuck game heals on the next robot trigger).

Companion core fix: nodots/backgammon-core#131 (stop offering the smaller-die move at Play.initialize).

Tests

New robot-bearoff-larger-die.test.ts reproduces the stale persisted play (both moves ready, smaller die first) with the exact GNU hint payload; asserts execution uses die 5 and the game completes. Red on main, green with the fix.

A GNU bear-off step carries no die value and the matcher compares
origin position only, so when both dice can bear off the same point
the first ready move in roll order won. Core's must-use-larger-die
rule rejects the smaller die when only one die can be played, so the
robot's turn was rejected on every retry and the game froze.

Production game 2d98cf14-e262-433c-baf5-95a2f878311d: one checker on
the 2-point, 14 off, roll [3,5] — the matcher picked die 3.

Sort ready moves by die value descending before matching. Point-to-
point and reenter matching is die-unique (origin+destination determine
the die), so the sort only affects the ambiguous bear-off case. Also
heals pre-fix plays persisted with both moves still ready.

Bump to 1.0.5.
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.

1 participant