- commit
- 0d99df69ecb44bbd2074364c2d803ce864759375
- parent
- 69851e2326f7a91642966f727f4ffeb374cba831
- author
- Dami <dami.etoile@gmail.com>
| M | mods/ | 10 | ++++++---- |
| M | tests/ | 18 | +++++++++++++++++- |
@@ -57,8 +57,8 @@ module.exports = {
5757 }),5858 5959 level(10, 5, [60- // ROCK starts with PUSH and STOP. Push STOP out of the sentence while61- // keeping ROCK IS PUSH, then move the rock to FLAG.60+ // ROCK carries PUSH and STOP at once. The level's direct route lets61+ // PUSH move the rock through its STOP property into FLAG.6262 word('MIAU', 0, 0, 'cargo-miau'), word('IS', 1, 0, 'cargo-miau-is'),6363 word('YOU', 2, 0, 'cargo-you'),6464 word('FLAG', 6, 0, 'cargo-flag'), word('IS', 7, 0, 'cargo-flag-is'),@@ -70,10 +70,12 @@ module.exports = {
7070 object('FLAG', 8, 3, 'cargo-flag-object'),7171 ], {7272 id: 'rules-are-cargo',73- title: 'Rules are cargo',74- hint: 'Push STOP upward out of ROCK IS PUSH AND STOP, then push the rock aside and step onto FLAG.',73+ title: 'Push beats stop',74+ hint: 'ROCK is STOP and PUSH at once. Which one wins when you walk into it?',7575 category: 'challenge',7676 introduces: ['PUSH', 'STOP'],77+ allowBypass: true,78+ allowHandsOff: true,7779 }),7880 ],7981 };@@ -3,6 +3,7 @@ import assert from 'node:assert/strict';
33 import { readFile } from 'node:fs/promises';44 import { createGame } from '../src/engine.js';55 import { loadMod } from '../src/mods.js';6+import { checkLevel } from '../src/solver/check-level.js';67 78 const source = await readFile(new URL('../mods/word-lab.cjs', import.meta.url), 'utf8');89 const pack = loadMod(source, { filename: 'word-lab.cjs' });@@ -20,6 +21,11 @@ test('Word Lab has a stable identity and three authored levels', () => {
2021 'rules-are-cargo',2122 ]);2223 assert.equal(pack.palette.GEM, '💎');24+ const cargo = pack.levels[2];25+ assert.equal(cargo.title, 'Push beats stop');26+ assert.equal(cargo.hint, 'ROCK is STOP and PUSH at once. Which one wins when you walk into it?');27+ assert.equal(cargo.allowBypass, true);28+ assert.equal(cargo.allowHandsOff, true);2329 });2430 2531 test('shared control uses AND to let ROCK solve the level while MIAU is stopped', () => {@@ -51,7 +57,7 @@ test('noun transformation changes ROCK into the controllable GEM', () => {
5157 assert.equal(game.getState().won, true);5258 });5359 54-test('PUSH takes precedence over STOP in Rules are cargo', () => {60+test('PUSH beats STOP in the authored cargo proof', () => {5561 const game = createGame(pack.levels[2]);5662 assert.equal(game.has('ROCK', 'PUSH'), true);5763 assert.equal(game.has('ROCK', 'STOP'), true);@@ -61,6 +67,16 @@ test('PUSH takes precedence over STOP in Rules are cargo', () => {
6167 assert.equal(game.has('ROCK', 'STOP'), true);6268 });6369 70+test('cargo proof imports cleanly and classifies its allowed routes', () => {71+ const result = checkLevel(pack.levels[2], { cap: 100_000 });72+ assert.equal(result.ok, true);73+ assert.equal(result.issues.length, 0);74+ assert.deepEqual(result.warnings, []);75+ assert.equal(result.checks.result.status, 'SOLVED');76+ assert.equal(result.checks.bypass.status, 'SOLVED');77+ assert.equal(result.checks.handsOff.status, 'SOLVED');78+});79+6480 test('editing a stacked predicate removes STOP while preserving PUSH', () => {6581 const game = createGame(pack.levels[2]);6682 move(game, 'right', 4);