feat(games): /games — a six-game arcade in the pit - #364
Merged
Conversation
`/games` lists the cabinet, `/games <game>` plays one. Six games — tetris, snake, pac-man, tic-tac-toe, chess and hangman — sharing one frame, one key decoder and one driver, so the arcade looks like an arcade rather than six weekend projects. No menus and no options screens: `/games tetris` is already playing when the frame lands, and every game reads arrows, quits on q and restarts on r, with its controls written along the bottom of the game itself. The games are pure — create a state, hand it a key, hand it a tick, ask it for rows — and everything touching a terminal lives in runGame(). That is what makes test/games.test.mjs able to finish real games of tetris and pac-man, prove the tic-tac-toe opponent cannot be beaten in 40 games of random play, and check chess's castling, en passant, promotion and mate detection without a TTY anywhere near it. Chess plays by the real rules against an alpha-beta search. Its reply runs on the clock rather than inside the keypress, so your own move is drawn before it starts thinking. Also available as `moshcode games` from a shell; listing works in a pipe, playing needs a real terminal and says so. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
| ], | ||
| seeAlso: ["help"], | ||
| note: "every game works the same way: arrows move, q quits, r starts another. " | ||
| + "Playing needs a real terminal because they read single keypresses — `moshcode games` on its own lists them anywhere.", |
ThreatCrush Security Scan95 finding(s) HIGH/CRITICAL: 5 | MEDIUM: 39 | LOW: 51
…and 45 more. Full results in the Security tab. Snippets are redacted; ThreatCrush never prints matched credential material. |
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
/gameslists the cabinet,/games <game>plays one.One arcade, not six weekend projects
Every game shares one frame, one key decoder and one driver, so they look
alike by construction: a title, a status, a boxed board, and one line of keys
along the bottom. No menus, no options screens, no difficulty prompts —
/games tetrisis already playing by the time the frame lands. Arrows move,qquits,rstarts another, everywhere.Games draw in place rather than on the alternate screen, so the board you
finished on stays in your scrollback, and an unchanged frame is not repainted
at all.
Why it is testable
The games are pure — create a state, hand it a key, hand it a tick, ask it for
rows — and everything that touches a terminal lives in
runGame(). Sotest/games.test.mjs(54 tests) plays real games with no TTY: it fills atetris well until it stacks out, walks pac-man around until the maze is
cleared, wins and loses hangman, and drives the driver itself through a fake
stdin.
Two of those tests are the kind you cannot do by hand:
lose
reachable — a walled-off pocket is a game that cannot be won
Chess gets the full rulebook: castling (refused through check), en passant,
promotion, check, checkmate and stalemate, each with a test. Its opponent is
an alpha-beta search that runs on the clock rather than inside the keypress,
so your own move is on the board and drawn before it starts thinking.
Surface
/games,/games <game>in the pit (aliases/game,/arcade,/play)moshcode games [game],moshcode games --jsonfrom a shell/help,moshcode help games, shell completion and the generatedREADME table — the existing drift guards required all of it
Playing needs a real terminal, because every game reads single keypresses;
listing works anywhere, including a pipe, and says so when it refuses.
Testing
node --test— 1411 pass, 0 failredraw, gravity, ghost movement, the machine's reply, and a clean exit that
restores the cursor
🤖 Generated with Claude Code