Skip to content

Checkers: Huevo chains can be continued by tapping (#879) - #880

Merged
margani merged 2 commits into
mainfrom
issue/391-huevo-chain-taps
Nov 13, 2026
Merged

margani merged 2 commits into
mainfrom
issue/391-huevo-chain-taps

Conversation

@margani

@margani margani commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

Closes #879

Reported by @HuevosKicker on #391: in Huevo Style a capture chain could never be continued by tapping.

What changed

  • www/games/checkers/index.html: the tap logic moved into the engine as pickOf (which squares are dots) and tapPick (what a tap does), and the page's pickState/tapSquare call them.
    • Huevo: every landing of every chain is a dot from the start. Tapping one plays the move that stops there, as the designer's write-up describes (H3). If different captures stop on the same square (a loop taken either way), that square becomes the goal and the route is picked hop by hop. This is used instead of the write-up's popup, so no new strings are needed in nine languages.
    • Classic and Spanish: same behaviour as before (the next landing only, played after the last tap). A new test checks it.
  • tools/tests/checkers-huevo-chains.js: 13 checks on real move lists: dots on every landing, the far tap plays the whole chain, the near tap stops, a king's middle landing, the two-route goal case, classic unchanged, and the page wiring.
  • tools/test.js: the wiring check now expects four E.moves(S.board, S.turn, S.rules, S.free, S) call sites, not three (the extra one is in tapSquare).

Not included: the reporter's Empress point (flying back over squares she captured earlier in the same move). It is a rule change the write-up does not state, so it waits for the owner.

Proof

New test group against origin/main's checkers: ✗ the engine has the tap logic (pickOf, tapPick), exit 1. On the branch: 13 of 13, exit 0.

Real taps in headless Chrome. Each run reports the folder its port served. Seeded Huevo board: a man on 49 can take 42 (landing 35), then 28 (landing 21).

OLD served=main   taps=49,21    pieces(49,35,21)=49:1 35:0 21:0 enemy men left=2   (21 is not a dot)
OLD served=main   taps=49,35,21 pieces(49,35,21)=49:0 35:1 21:0 enemy men left=1   (the move ends after one hop)
NEW served=branch taps=49,21    pieces(49,35,21)=49:0 35:0 21:1 enemy men left=0
NEW served=branch taps=49,35    pieces(49,35,21)=49:0 35:1 21:0 enemy men left=1   (stopping early still works)
  • node tools/test.js: all 10182 checks green, exit 0.
  • tools/browser-check.sh: 75 of 75 pages, exit 0.
  • Screenshots looked at: phone 390 px in English light and Persian dark (dots on 35, 21 and the quiet step 40), and desktop 1280 px after the chain (piece on 21, both men taken).

🤖 Generated with Claude Code

Huevo: every landing of the chain is a dot

In Huevo every landing is a legal end of the move, so the tap handler,
which plays a move as soon as one matches the landings tapped so far,
played the first hop at once and no chain could be continued. As the
designer's write-up asks, every landing of every chain is now a dot and
a tap plays the move that stops there; when different captures stop on
the same square, the route is picked hop by hop. Classic and Spanish
taps are unchanged. The tap logic lives in the engine (pickOf, tapPick)
so Node tests can drive it.

Reported by HuevosKicker on #391.

Closes #879

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@margani

margani commented Nov 13, 2026

Copy link
Copy Markdown
Contributor Author

Diff review

Why this shape: in Huevo, jumps() pushes a move at every landing, and the old tapSquare played the first move whose path length matched the taps. In classic and Spanish that only matches at a chain's end, so the bug was Huevo-only. Instead of patching the length check, the decision moved into two pure engine functions (pickOf, tapPick), so Node can test the page's tap behaviour against real E.moves lists. The page passes only the picked piece's moves, as pickState filtered them before.

The reporter suggested a popup for ambiguous endpoints. Here the square becomes a goal and the dots narrow to the first hops of the routes that end there. That needs no new strings (nine locales). distinct() keys moves by their capture set: two paths with the same captures and end square leave the same board.

Tested: the new group (fails on main because the functions are missing, 13/13 on the branch), the whole suite, browser-check, and real taps through Chrome on old and new code (table in the PR body). Classic forced-chain tapping is covered by its own check.

Not tested: keyboard play of a Huevo chain (Enter calls the same tapSquare, so it takes the same path), and the hop-by-hop goal case in the browser (unit-tested only; it needs a loop position, which is rare). The AI path is untouched: it never uses the tap logic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@margani
margani merged commit 03f5ae7 into main Nov 13, 2026
4 checks passed
@margani
margani deleted the issue/391-huevo-chain-taps branch November 13, 2026 00:31
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.

Checkers Huevo Style: capture chains cannot be continued by tapping

1 participant