feat(tools): play-spellgrid stages the M10 reference with cards and levels and runs its CLI
Lesson 10 and both M10 reference READMEs now give the real recipe (node tools/play-spellgrid.mjs <rust|ts> [l1|l2|l3]); root script play:spellgrid. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ad0701395d
commit
bb98be089a
6 files changed
+144
-8
No files matched your search
@@ -249,13 +249,15 @@ syncRules(): // seam 1
|
||||
|
||||
### Play it
|
||||
|
||||
The reference ships a command line, kept thin over the harness. From a workspace with `cards/` and `levels/`:
|
||||
The reference ships a command line, kept thin over the harness. It reads `cards/` and `levels/` from the directory it runs in, so `tools/play-spellgrid.mjs` stages the reference with the course's cards and levels into a temporary directory and starts it. From the course repository:
|
||||
|
||||
```sh
|
||||
cargo run --bin spellgrid -- levels/l1-double-tap.json # Rust
|
||||
npx tsx src/cli.ts levels/l1-double-tap.json # TypeScript
|
||||
node tools/play-spellgrid.mjs rust l1 # Rust: cargo run --bin spellgrid -- levels/l1-double-tap.json
|
||||
node tools/play-spellgrid.mjs ts l1 # TypeScript: npx tsx src/cli.ts levels/l1-double-tap.json
|
||||
```
|
||||
|
||||
The level is `l1`, `l2` or `l3` (or a path to a level file of your own). `--dir <dir>` stages into a directory you choose and keeps it, and `--stage-only` prints the command without running it. The tool prints where it staged, so you can run the command there again.
|
||||
|
||||
`w`, `a`, `s`, `d` play a turn; `c <card> [x y]` casts a spell (at the minion on that tile, if given) or plays a minion (onto that empty tile); `q` quits. Graft asks for its base, donor and half; answer with a number or a name. Writing your own is optional: the course's tests don't call it.
|
||||
|
||||
## Name it
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
The course's own engine as of the end of Module 10: Part I's card engine and Part II's grid engine, joined by SpellGrid. Every test from Modules 1–9 still passes. Module 9's reference was the starting point, so a diff between the two shows what this module adds.
|
||||
|
||||
- `cards/` and `levels/` (at the crate root; not in this directory): copies of `course/cards/` plus `course/10-spellgrid/cards/` (SpellGrid's own cards, which only Module 10 on receives), and of `course/10-spellgrid/levels/`, staged by `tools/verify-references.mjs`.
|
||||
- `cards/` and `levels/` (at the crate root; not in this directory): copies of `course/cards/` plus `course/10-spellgrid/cards/` (SpellGrid's own cards, which only Module 10 on receives), and of `course/10-spellgrid/levels/`, staged by `tools/verify-references.mjs` (and by `tools/play-spellgrid.mjs`, to play the command line).
|
||||
- `src/engine/spellgrid.rs` (new): the only module that uses both engines. `SpellGrid` keeps a `World` and a `puzzle::Level` in step through the three seams: `rule_auras` (rules in force → auras), `CardSide::destroy` (hazard victims → one `Destroy` Sequence → the Death Creation Step), and `CardSide::sequence` (after each Sequence: write `TextSpawned` text, take dead minions off the grid, reparse). It also keeps one id space: a minion's id is its grid object's id.
|
||||
- Part I (`src/engine/`, outside `puzzle/`):
|
||||
- `queue.rs`: `END_OF_PHASE` (`[DeathCreation, AuraUpdate]`) is the list of steps at the end of the outermost Phase, read from the world. `Action::SpawnText` records a `TextSpawned` event.
|
||||
@@ -15,6 +15,6 @@ The course's own engine as of the end of Module 10: Part I's card engine and Par
|
||||
- `grid.rs`: `Board::reserve_id`, and `cards`/`hand` in `LevelDef` (read only by SpellGrid), with `LevelCard`.
|
||||
- `src/content/seams.json` and `seams()` (new): which nouns name a trigger (`DEATHRATTLE`) and which properties multiply one (`DOUBLE`, twice, `stacking: "max"`). `words.json` adds the SpellGrid nouns, `DEATHRATTLE` and `DOUBLE`.
|
||||
- `src/harness.rs`: Module 10 adds `new_spell_grid` and `SpellGrid`, including the test hook `with_naive_aura_timing()`, which reverses `END_OF_PHASE` for one game.
|
||||
- `src/cli.rs` and `src/bin/spellgrid.rs` (new): the command line, `cargo run --bin spellgrid -- levels/l1-double-tap.json` from a staged workspace (it needs `cards/` and `levels/`). `w a s d` move, `c <card> [x y]` casts a spell (at the minion on that tile) or plays a minion (onto that empty tile), `q` quits. `tests/cli.rs` plays it from a script; it is the reference's own check, not a course test.
|
||||
- `src/cli.rs` and `src/bin/spellgrid.rs` (new): the command line, `cargo run --bin spellgrid -- levels/l1-double-tap.json` run from a staged directory (it needs `cards/` and `levels/`): `node tools/play-spellgrid.mjs rust l1` from the course repository stages one in a temporary directory and starts it. `w a s d` move, `c <card> [x y]` casts a spell (at the minion on that tile) or plays a minion (onto that empty tile), `q` quits. `tests/cli.rs` plays it from a script; it is the reference's own check, not a course test.
|
||||
|
||||
Run it with the module's tests: `node tools/verify-references.mjs 10` from the course repository.
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
The course's own engine as of the end of Module 10: Part I's card engine and Part II's grid engine, joined by SpellGrid. Every test from Modules 1–9 still passes. Module 9's reference was the starting point, so a diff between the two shows what this module adds.
|
||||
|
||||
- `cards/` and `levels/` (at the package root; not in this directory): copies of `course/cards/` plus `course/10-spellgrid/cards/` (SpellGrid's own cards, which only Module 10 on receives), and of `course/10-spellgrid/levels/`, staged by `tools/verify-references.mjs`.
|
||||
- `cards/` and `levels/` (at the package root; not in this directory): copies of `course/cards/` plus `course/10-spellgrid/cards/` (SpellGrid's own cards, which only Module 10 on receives), and of `course/10-spellgrid/levels/`, staged by `tools/verify-references.mjs` (and by `tools/play-spellgrid.mjs`, to play the command line).
|
||||
- `src/engine/spellgrid.ts` (new): the only file that imports both engines. `SpellGrid` keeps a `World` and a `puzzle.Level` in step through the three seams: `ruleAuras` (rules in force → auras), the destroy function (hazard victims → one `destroy` Sequence → the Death Creation Step), and `sequence` (after each Sequence: write `TextSpawned` text, take dead minions off the grid, reparse). It also keeps one id space: a minion's id is its grid object's id.
|
||||
- Part I (`src/engine/`, outside `puzzle/`):
|
||||
- `queue.ts`: `END_OF_PHASE` (`["deathCreation", "auraUpdate"]`) is the list of steps at the end of the outermost Phase, read from the world. The `spawnText` action records a `TextSpawned` event.
|
||||
@@ -15,6 +15,6 @@ The course's own engine as of the end of Module 10: Part I's card engine and Par
|
||||
- `grid.ts`: `Board.reserveId`, and `cards`/`hand` in `LevelDef` (read only by SpellGrid).
|
||||
- `src/content/seams.json` and `seams()` (new): which nouns name a trigger (`DEATHRATTLE`) and which properties multiply one (`DOUBLE`, twice, `stacking: "max"`). `words.json` adds the SpellGrid nouns, `DEATHRATTLE` and `DOUBLE`. `index.ts` now reads `cards/` with `node:fs`, so the command line, which runs without Vite, reads the same cards.
|
||||
- `src/harness.ts`: Module 10 adds `newSpellGrid` and the `SpellGrid` interface, including the test hook `withNaiveAuraTiming()`, which reverses `END_OF_PHASE` for one game.
|
||||
- `src/cli.ts` (new): the command line, `npx tsx src/cli.ts levels/l1-double-tap.json` from a staged workspace (it needs `cards/` and `levels/`). `w a s d` move, `c <card> [x y]` casts a spell (at the minion on that tile) or plays a minion (onto that empty tile), `q` quits. `tests/cli.test.ts` plays it from a script; it is the reference's own check, not a course test.
|
||||
- `src/cli.ts` (new): the command line, `npx tsx src/cli.ts levels/l1-double-tap.json` run from a staged directory (it needs `cards/` and `levels/`): `node tools/play-spellgrid.mjs ts l1` from the course repository stages one in a temporary directory and starts it. `w a s d` move, `c <card> [x y]` casts a spell (at the minion on that tile) or plays a minion (onto that empty tile), `q` quits. `tests/cli.test.ts` plays it from a script; it is the reference's own check, not a course test.
|
||||
|
||||
Run it with the module's tests: `node tools/verify-references.mjs 10` from the course repository.
|
||||
Reference in new issue
Block a user