Skip to content

Arimaa Input QoL - #477

Merged
Perlkonig merged 2 commits into
AbstractPlay:developfrom
samtcifihi:arimaa-input-2026-09-18
Sep 19, 2026
Merged

Perlkonig merged 2 commits into
AbstractPlay:developfrom
samtcifihi:arimaa-input-2026-09-18

Conversation

@samtcifihi

Copy link
Copy Markdown
Contributor

Arimaa: fewer clicks during setup

Implements both changes from this proposal. The two parts are independent; neither depends on the other.

Also fixes a minor bug Claude found.

1. Fill empty setup squares with rabbits (standard setup)

A player now only has to place their eight non-rabbits. Once those are down, the setup validates as submittable (complete: 0, so Complete Move appears), and the submitted move is topped up with rabbits on the remaining empty cells of that player's own two ranks.

This halves the clicks for the standard game: Ee2,Md2,Hb2,Hg2,Cf2,Cc2,Dd1,De1 — eight clicks — expands to the full sixteen-piece setup. It also pairs with the existing strongest-piece-first click default, which is what makes EMHHDDCC fall out of eight clicks in the first place.

Rabbits placed by hand are left exactly where the player put them, so anyone who wants a rabbit somewhere in particular can still place any or all of them first and let the rest fill in.

Two details worth a look:

  • The setup advice (balance, hiding, elephant file) is now evaluated against the filled-in setup rather than the partial one, so the warnings a player sees are the ones that apply to the position they'll actually play.
  • The expansion runs in move() before anything is recorded, and is a no-op on a setup that's already complete. Recorded notation therefore stays fully explicit — a game set up via the shortcut records all sixteen placements in lastmove.

The 99 preset buttons are unaffected; they leave D,D,C,C in hand, so they still validate as incomplete exactly as before.

2. Default to rabbits in free setup

Clicking an empty cell with no piece selected now places a rabbit in free setup only. The free-setup hand is never consumed, so "strongest piece remaining" was permanently the elephant there, which cost two clicks per rabbit — a stash click plus a board click.

Standard setup is untouched and still offers the strongest piece still in hand.

Measured: sixteen pieces including one elephant in free setup goes from 31 clicks to 17 (I think Claude used 15 rabbits for this test; that's what would give this result. Actual gains in practice will be much more modest, but still significant).

3. Bug fix: two placements on one cell

Separate commit, and the part I'd most like a second opinion on.

The "cell must be empty" check in setup validation tested this.board — the board as it stood at the start of the turn — rather than the working copy the loop accumulates placements into. So a move string naming one cell twice got past it.

Only reachable by typing. The click handler declines to drop a held piece onto an occupied cell (Ee2,M + click e2 → Ee2), and unplacing removes the step from the move rather than overwriting it. It never allowed an illegal move to be submitted, but it failed badly in two different ways:

  • Standard setup: the hand emptied while a home cell stayed empty, so the hiding-advice check dereferenced an empty cell it assumed was filled and threw an unhandled TypeError, surfacing as "a generic error occurred".
  • Free setup: accepted silently, with the second piece replacing the first. Ec3,Mc3,Rd4 gave three placements, two pieces on the board, camel on c3.

Testing cloned.board fixes both — the cell is reported as occupied, same as placing onto an opponent's piece. The working copy starts as a clone of the board, so this is strictly a superset of what the old check caught, and no legitimate move names a cell twice. If there was a reason for reading this.board there that I've missed, I'm happy to drop this commit and open it as an issue instead.

No version bump

Nothing here changes the outcome of a previously legal sequence. Replays go through src/common/replay.ts, which calls move(m, {trusted: true}) and skips validation entirely, so tightening validation can't affect any stored game.

I checked the rollback case rather than assuming it: a game created via the eight-click shortcut, loaded with the pre-change engine, replays and re-validates to an identical signature and continues play normally. Reverting this orphans nothing.

Exposure is also bounded structurally — the autofill only engages while the mover has pieces in hand in a no-variant game, i.e. plies 1–2. After setup, hands is cleared and the helper returns immediately for the rest of the game.

Files

  • src/games/arimaa.ts
  • test/games/arimaa.test.ts
  • locales/en/apgames.json — one new key, validation.arimaa.PARTIAL_RABBITS, plus a paragraph in notes.arimaa documenting the shortcut. Other locales left to Weblate.

samtcifihi and others added 2 commits September 18, 2026 20:17
Two independent input conveniences for the setup phase.

In standard setup, a player now only has to place their eight
non-rabbits. Once those are down, the setup validates as submittable
(so Complete Move appears) and the submitted move is topped up with
rabbits on the remaining empty cells of the player's setup area.
Rabbits placed by hand are left alone, so anyone who wants a rabbit
somewhere in particular can still put it there. The setup advice
(balance, hiding, elephant file) is evaluated against the filled-in
setup rather than the partial one.

In free setup, clicking an empty cell with nothing selected now
places a rabbit instead of an elephant. The free hand never empties,
so "strongest piece remaining" was always the elephant there, which
meant two clicks per rabbit. A 16-piece free setup with one elephant
drops from 31 clicks to 17.

Standard setup is unchanged in this respect and still offers the
strongest piece still in hand, which now pairs with the autofill
above: EMHHDDCC in eight clicks.

The expansion is a no-op on a setup that is already complete, and
runs before anything is recorded, so stored notation stays fully
explicit and existing games replay identically. No version bump.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDibMmzgf18ky9fiCRW5cL
The "cell must be empty" check in setup validation tested the board as
it stood at the start of the turn rather than the working copy the loop
is accumulating placements into, so a move string naming one cell twice
got past it. Only reachable by typing: the click handler declines to
drop a held piece onto an occupied cell, and unplacing removes the step
from the move rather than overwriting it.

It never let an illegal move be submitted, but it failed badly in two
different ways. In standard setup the hand emptied while a home cell
stayed empty, so the setup advice hit an empty cell it assumed was
filled and threw an unhandled TypeError, surfacing as "a generic error
occurred". In free setup, where pieces are not consumed from the hand,
it was accepted silently and the second piece replaced the first.

Checking the working copy fixes both: the cell is now reported as
occupied, the same as placing onto an opponent's piece. The working
copy starts as a clone of the board, so this is strictly a superset of
what the old check caught, and no legitimate move names a cell twice.

Replays run trusted and skip validation, so no stored game is affected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDibMmzgf18ky9fiCRW5cL
@Perlkonig

Copy link
Copy Markdown
Member

I always love fixing bugs, so thank you! And great idea to auto-populate the rabbits.

@Perlkonig
Perlkonig merged commit 4d2508e into AbstractPlay:develop Sep 19, 2026
1 check passed
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