First Part II module. The cumulative reference adds a second engine (src/engine/puzzle: grid, lexer, parser) beside Part I's; nouns and properties are data in src/content/words.json, and the engine names only IS/AND/NOT/TEXT and the base rule TEXT IS PUSH. Rules are recompiled from the board on every change; rules() is a sorted set. Adds the M6 scenarios and tests (rows, columns, shared IS, AND distribution, stacked text, base rule), the HOT word as a data-only Expansion Drop, the lesson with the Part II bridge, and the Rust LevelDef shape in harness.md. Co-Authored-By: Claude Opus 5.5 <[email protected]>
40 lines
3.5 KiB
Markdown
40 lines
3.5 KiB
Markdown
# Module 6 scenarios: Grid, lexer and parser
|
|
|
|
Each heading is a test name. The Rust test lives in `tests/rust/test_06.rs` and the TypeScript test in `tests/ts/test_06.test.ts`; both state exactly what is written here.
|
|
|
|
Part II has its own harness object, `Baba`, made by `newBaba(level)` from a level in the format of `course/schema/level.schema.json`: a `width`, a `height` and a list of `objects`, each `{kind, x, y}`. `x` grows right and `y` grows down. A kind is either an object (`"baba"`) or a word of text (`"text:BABA"`). `place(kind, x, y)` adds one more object to the level and returns its id. Several objects may share a tile.
|
|
|
|
`rules()` returns every rule the board currently spells, as normalised strings such as `"BABA IS YOU"`, sorted, each distinct rule once. The base rule `"TEXT IS PUSH"` is always in it, although no text spells it. Duplicates are a real thing in the game (stacked text "will attempt to produce all possible rules", and a rule spelled twice can duplicate objects, see `docs/research/baba-is-you.md` §e), so the engine may hold the same rule more than once, but `rules()` is the set of distinct rules and no test counts duplicates.
|
|
|
|
Words used: the nouns `BABA`, `ROCK`, `FLAG`; the properties `YOU`, `WIN`, `PUSH`, `STOP`; the operators `IS` and `AND`; the meta-noun `TEXT` (only through the base rule). Rules read left to right in a row and top to bottom in a column. A test writes a sentence as its words with their tiles: `BABA (0,0) IS (1,0) YOU (2,0)` is three text objects, `text:BABA` at x 0, y 0, and so on.
|
|
|
|
### test_06_horizontal_rule
|
|
|
|
- Setup: `newBaba` with a level 5 wide and 3 high whose `objects` are, in this order: `BABA (0,0) IS (1,0) YOU (2,0)`; an object `baba` at (3,2); `YOU (0,2) IS (1,2) FLAG (2,2)`.
|
|
- Action: none. The rules come from the level's objects.
|
|
- Assertions:
|
|
- `rules()` is exactly `["BABA IS YOU", "TEXT IS PUSH"]`.
|
|
- Row 2 spells nothing: `YOU IS FLAG` has a property where a noun must start the sentence, and the parser never reads right to left (`FLAG IS YOU`). The `baba` object is not text and plays no part in parsing.
|
|
|
|
### test_06_crossword_shared_is
|
|
|
|
- Setup: `newBaba` with an empty level 3 wide and 3 high. Place `BABA (0,1)`, `IS (1,1)`, `YOU (2,1)`, then `FLAG (1,0)`.
|
|
- Assertions 1: `rules()` is exactly `["BABA IS YOU", "TEXT IS PUSH"]`. `FLAG` above `IS` is half a sentence.
|
|
- Action: place `WIN (1,2)`.
|
|
- Assertions 2: `rules()` is exactly `["BABA IS YOU", "FLAG IS WIN", "TEXT IS PUSH"]`. The `IS` at (1,1) is in a row sentence and a column sentence at once, and the rules were recompiled when the board changed.
|
|
|
|
### test_06_and_distributes
|
|
|
|
- Setup: `newBaba` with an empty level 7 wide and 1 high. Place `BABA (0,0) AND (1,0) ROCK (2,0) IS (3,0) PUSH (4,0) AND (5,0) STOP (6,0)`.
|
|
- Assertions: `rules()` is exactly `["BABA IS PUSH", "BABA IS STOP", "ROCK IS PUSH", "ROCK IS STOP", "TEXT IS PUSH"]`. AND distributes over both sides: two subjects times two complements is four rules.
|
|
|
|
### test_06_stacked_text_all_combinations
|
|
|
|
- Setup: `newBaba` with an empty level 3 wide and 1 high. Place `text:BABA` at (0,0), then `text:ROCK` also at (0,0), then `IS (1,0)` and `YOU (2,0)`.
|
|
- Assertions: `rules()` is exactly `["BABA IS YOU", "ROCK IS YOU", "TEXT IS PUSH"]`. Both stacked words start a sentence: the parser produces every rule the stack allows.
|
|
|
|
### test_06_default_text_is_push
|
|
|
|
- Setup: `newBaba` with a level 3 wide and 3 high whose only object is a `baba` at (1,1).
|
|
- Assertions: `rules()` is exactly `["TEXT IS PUSH"]`. No text spells it: it is a base rule of the game.
|