clone

a browser grid puzzle game where you push words around to rewrite the rules of each level

Teach unmaking PUSH in core proof two

Dami committed 02f34bc
commit
02f34bc5524a63c09f08a6b44196c853fd52941f
parent
279e7d61820f53fd56ad28e601df7800e2d6d0ba
author
Dami <dami.etoile@gmail.com>
2 files changed, +20 -25
Msrc/levels.js18++++++++----------
Mtests/levels.test.js27++++++++++++---------------
M src/levels.js +8 -10
@@ -24,14 +24,14 @@ export const levels = [
2424 },2525 {2626 id: 'make-room-to-push',27- title: 'Make room to push',28- hint: 'Break STOP, then push ROCK along the upper lane to FLAG.',27+ title: 'Stuck at the end',28+ hint: 'Pushed all the way, the rock jams against the edge. Does it have to be pushable?',2929 width: 12,3030 height: 9,3131 objects: [3232 { kind: 'object', noun: 'MIAU', x: 1, y: 5 },33- { kind: 'object', noun: 'ROCK', x: 4, y: 3 },34- { kind: 'object', noun: 'FLAG', x: 10, y: 3 },33+ { kind: 'object', noun: 'ROCK', x: 4, y: 5 },34+ { kind: 'object', noun: 'FLAG', x: 11, y: 5 },3535 ...Array.from({ length: 12 }, (_, x) => x === 1 ? null : ({ kind: 'object', noun: 'WALL', x, y: 4 })).filter(Boolean),3636 ...Array.from({ length: 12 }, (_, x) => ({ kind: 'object', noun: 'WALL', x, y: 6 })),3737 { kind: 'word', text: 'MIAU', x: 3, y: 0 },
@@ -40,12 +40,9 @@ export const levels = [
4040 { kind: 'word', text: 'FLAG', x: 6, y: 0 },4141 { kind: 'word', text: 'IS', x: 7, y: 0 },4242 { kind: 'word', text: 'WIN', x: 8, y: 0 },43- { kind: 'word', text: 'ROCK', x: 6, y: 1 },44- { kind: 'word', text: 'IS', x: 7, y: 1 },45- { kind: 'word', text: 'PUSH', x: 8, y: 1 },46- { kind: 'word', text: 'ROCK', x: 1, y: 1 },47- { kind: 'word', text: 'IS', x: 1, y: 2 },48- { kind: 'word', text: 'STOP', x: 1, y: 3 },43+ { kind: 'word', text: 'ROCK', x: 6, y: 2 },44+ { kind: 'word', text: 'IS', x: 7, y: 2 },45+ { kind: 'word', text: 'PUSH', x: 8, y: 2 },4946 // Keep the wall rule in the sealed lower area so it cannot be disabled5047 // as a shortcut around the corridor lesson.5148 { kind: 'word', text: 'WALL', x: 5, y: 8 },
@@ -57,6 +54,7 @@ export const levels = [
5754 id: 'two-things-can-win',5855 title: 'Two things can win',5956 allowBypass: true,57+ allowHandsOff: true,6058 hint: 'Read ROCK AND FLAG IS WIN, then reach the rock.',6159 width: 12,6260 height: 9,
M tests/levels.test.js +12 -15
@@ -38,26 +38,23 @@ test('level 1 teaches that breaking STOP changes movement', () => {
3838 assert.equal(game.getState().won, true);3939 });4040 41-test('level 2 preserves PUSH while STOP is removed', () => {41+test('level 2 jams a pushed rock at the flag until its PUSH rule changes', () => {4242 const game = createGame(levels[1]);4343 assert.equal(game.has('ROCK', 'PUSH'), true);44- assert.equal(game.has('ROCK', 'STOP'), true);4544 assert.equal(game.has('WALL', 'STOP'), true);46-47- move(game, 'up', 2); // Enter the gap and push the vertical STOP sentence.48- move(game, 'left');49- move(game, 'up');50- move(game, 'right'); // Nudge STOP sideways to finish breaking the rule.51- assert.equal(game.has('ROCK', 'STOP'), false);52- assert.equal(game.has('ROCK', 'PUSH'), true);53- assert.equal(game.has('WALL', 'STOP'), true);54- move(game, 'down', 3); // Return to the corridor entrance.55- move(game, 'right', 8); // Reach ROCK and push it to x=10.45+ move(game, 'right', 10);5646 const rock = game.getState().objects.find(object => object.kind === 'object' && object.noun === 'ROCK');57- assert.equal(rock.x, 10);47+ assert.equal(rock.x, 11);5848 assert.equal(game.getState().won, false);59- move(game, 'right'); // Push ROCK through FLAG to x=11; MIAU enters FLAG.60- assert.equal(game.getState().won, true);49+50+ const solved = createGame(levels[1]);51+ const steps = { U: [0, -1], D: [0, 1], L: [-1, 0], R: [1, 0] };52+ const route = 'UURRRRRUDLLLLLDDRRRRRRRRRR';53+ for (const [index, direction] of [...route].entries()) {54+ solved.step(...steps[direction]);55+ if (index === 7) assert.equal(solved.has('ROCK', 'PUSH'), false);56+ }57+ assert.equal(solved.getState().won, true);6158 });6259 6360 test('level 3 teaches an AND subject list', () => {