Add Checkers, Backgammon, Mastermind, and Pirates and Bulgars

The four games that were listed but not written. Nothing in the
catalogue is marked "coming soon" any more.

Checkers is English draughts on the thirty-two dark squares, numbered
the way the game is written down. Captures are compulsory and a multiple
jump is one move object, so a player cannot stop halfway through one —
true by construction rather than by a rule that has to be enforced
somewhere. The move generator matches the published perft counts at one
to four ply (7, 49, 302, 1469), which fold in compulsory capture,
crowning and the men's forward-only rule all at once.

Backgammon's hard rule is not how a checker moves but that a player must
use as much of the roll as they can, and that cannot be checked one move
at a time: a move can be illegal precisely because playing it strands
the other die. So the generator works backwards from whole turns —
memoised depth-first over the remaining dice — and offers only the first
steps of the longest plays. Recomputing it after each checker is what
makes the rule true by construction. Every die comes from the table's
seed and a count of rolls made, which is in the state rather than beside
it so a game is reproducible from what crosses the wire. There is no
doubling cube; the rules document says so plainly.

Mastermind is played as a duel — both players are set a code and both
are breaking one — because the pencil-and-paper game gives the codemaker
nothing to do. It ends at the foot of a round, never mid-round, or going
first would be worth half a guess. It is the one game here with anything
to hide, so viewFor does real work: the host sends each device only its
own code, and a device that was never given a code refuses to score a
guess against it rather than quietly answering "nothing".

Pirates and Bulgars is Sackson's theming of Asalto, and the rules
document is explicit about which parts are attested and which had to be
chosen — the book could not be obtained. Two hunters who take by
jumping against twenty-four who cannot take at all, on a thirty-three
point cross whose drawn lines come from the same adjacency table the
moves come from, so the board and the rules cannot disagree.

130 unit tests across the four engines, all run locally as well as in
CI: game/ has no Android in it, which is what makes that possible.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019Pr6B8xDDtJJcb6WJMw7Ud
This commit is contained in:
Claude
2026-08-07 07:58:12 +00:00
parent 23286090f1
commit 284f9f3f95
29 changed files with 6299 additions and 20 deletions
+24 -10
View File
@@ -5,20 +5,23 @@ or against other people over Wi-Fi (LAN).
## What works today
The app shell is complete and ten games are playable end to end:
The app shell is complete and every game in the catalogue is playable end to end:
| | |
| --- | --- |
| **Playable** | Euchre, Kaiser, President, Golf, Wizard, Crazy 8s, Sequence, Chess, Ta Yü, Nine Men's Morris |
| **Listed, not yet implemented** | Mastermind, Backgammon, Checkers, Pirates and Bulgars |
| **Cards** | Euchre, Kaiser, President, Golf, Wizard, Crazy 8s |
| **Board** | Sequence, Chess, Checkers, Backgammon, Mastermind, Nine Men's Morris, Pirates and Bulgars, Ta Yü |
Unimplemented games appear in the menu marked *Coming soon* **on dev builds
only** — a production release lists just the games that can actually be played,
so nobody installs it and taps into a dead end. The menu decides this from the
installed APK's own version name, so it follows the build rather than the
channel selected for future updates. Adding one means
writing a `GameRules` implementation, a `GameAi`, and a screen, then flipping
`available` in `GameCatalog` — the menu, lobby, networking, settings and OTA
Nothing is marked *Coming soon* at the moment, because nothing is waiting. The
machinery for it is still there and still tested: a game listed in `GameCatalog`
with `available = false` appears in the menu marked *Coming soon* **on dev builds
only**, so a production release lists just what can actually be played and nobody
installs it and taps into a dead end. The menu decides this from the installed
APK's own version name, so it follows the build rather than the channel selected
for future updates.
Adding a game means writing a `GameRules` implementation, a `GameAi` and a
screen, then flipping `available` — the menu, lobby, networking, settings and OTA
layers are game-agnostic and need no changes.
## Playing with other people
@@ -269,7 +272,14 @@ game:
- [Wizard](docs/RULES-wizard.md)
- [Crazy 8s](docs/RULES-crazy8s.md)
- [Chess](docs/RULES-chess.md)
- [Checkers](docs/RULES-checkers.md) — **note the caveat about flying kings**
- [Backgammon](docs/RULES-backgammon.md) — **note that there is no doubling cube**
- [Mastermind](docs/RULES-mastermind.md) — played as a duel, both players
guarding a code and breaking one
- [Nine Men's Morris](docs/RULES-morris.md)
- [Pirates and Bulgars](docs/RULES-pirates.md) — **note the caveats about the
reconstruction**: the book the theme comes from could not be obtained, so the
document says which rules are attested and which were chosen
- [Ta Yü](docs/RULES-tayu.md) — **note the caveats about the reconstruction**:
the game is out of print and the rulebook could not be obtained, so the
document says which parts are attested and which were derived
@@ -289,6 +299,10 @@ game/ rules engines and AI — pure Kotlin, no Android, unit-tested
crazyeights/ Crazy 8s model, rules, AI
chess/ Chess model, FEN, move generation, search
morris/ Nine Men's Morris board geometry, mills, rules, search
checkers/ Checkers board, compulsory captures, crowning, search
backgammon/ Backgammon points, dice, the maximal-roll rule, turn search
mastermind/ Mastermind codes, scoring, and a code breaker
pirates/ Pirates and Bulgars — the cross board, the hunt, search
tayu/ Ta Yü tile geometry, river rules, scoring, AI
net/ wire protocol, LAN transport, lobby, match driver
score/ scorekeeper sheet — pure Kotlin, unit-tested — and its store