Public: anyone can read this; the crew can change it.

Migrated from github.com/amirmushichge/pixel-plays

Tide Crossing rules: a tested `tide-crossing/causeway.js` where you step across a stone causeway to the island before the tide covers your path, within par, in a two-file pull with a test file that runs in under a second #346

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

This adds the Tide Crossing rules and their tests in two files: `tide-crossing/causeway.js` and `tide-crossing/causeway.test.mjs`. Nothing else is touched, and there is no page or catalogue entry yet. All 14 tests pass, and `bun test tide-crossing/causeway.test.mjs` took 41 ms in the test runner (0.046 s wall). The test file loads no page, renderer or server.

shipped production is serving it deploy 5b5fb07

opened this

This adds the Tide Crossing rules and their tests in two files: tide-crossing/causeway.js and tide-crossing/causeway.test.mjs. Nothing else is touched, and there is no page or catalogue entry yet. All 14 tests pass, and bun test tide-crossing/causeway.test.mjs took 41 ms in the test runner (0.046 s wall). The test file loads no page, renderer or server.

What the rules do

  • Water rule: a stone of height h is under water at tick t exactly when tide[t] >= h. Past the end of the table the tide holds its last value. The units are stated in the file header.
  • start(level): takes a level index (anything unknown gives level 0) and returns plain data. There are six hand-made levels: Short hop, Low stones, The bend, Wait for the ebb, Two ways and Spring tide. Each has a stone grid, start, goal, tide table, par and a stated solution.
  • move(state, dir): steps to a neighbouring stone that is above water on the next tick, then the tide advances one tick.
  • wait(state): stays put for one tick.
  • Refusals: unknown-direction, no-stone, under-water and game-over all return the identical state object.
  • Loss and win lines: a loss reads "Lost: the tide covered your stone at tick N". A win reads "Crossed in N ticks against par P: on par", or "N under par" or "N over par".
  • restart(state): always allowed, and returns the level fresh.

What the tests check

  • Every level's stated solution wins within par, and a breadth-first search confirms par is the true minimum.
  • Two levels cannot be crossed without waiting: Wait for the ebb and Spring tide. In Wait for the ebb, hurrying is refused as under-water.
  • Each refusal and its reason, the loss line with its tick, the win line on, under and over par, and restart.
  • The rules don't mutate the state they are given.

Choices to look at

  • wait never refuses for a covered stone. It drowns you, because that is the only way to be "caught by the tide". move refuses covered stones, so it can never drown you.
  • Ticks used counts waits as well as moves, and par is stated in ticks.
  • I did not run the repo's scripts/gate.ts or scripts/fast.ts, because the clone has neither. bun x tsc --noEmit printed only its help text, since the repo has no tsconfig. No dependencies were added.

Closes #328

commented

This adds the Tide Crossing rules and their tests in two files: tide-crossing/causeway.js and tide-crossing/causeway.test.mjs. Nothing else is touched, and there is no page or catalogue entry yet. All 14 tests pass, and bun test tide-crossing/causeway.test.mjs took 41 ms in the test runner (0.046 s wall). The test file loads no page, renderer or server.

What the rules do

  • Water rule: a stone of height h is under water at tick t exactly when tide[t] >= h. Past the end of the table the tide holds its last value. The units are stated in the file header.
  • start(level): takes a level index (anything unknown gives level 0) and returns plain data. There are six hand-made levels: Short hop, Low stones, The bend, Wait for the ebb, Two ways and Spring tide. Each has a stone grid, start, goal, tide table, par and a stated solution.
  • move(state, dir): steps to a neighbouring stone that is above water on the next tick, then the tide advances one tick.
  • wait(state): stays put for one tick.
  • Refusals: unknown-direction, no-stone, under-water and game-over all return the identical state object.
  • Loss and win lines: a loss reads "Lost: the tide covered your stone at tick N". A win reads "Crossed in N ticks against par P: on par", or "N under par" or "N over par".
  • restart(state): always allowed, and returns the level fresh.

What the tests check

  • Every level's stated solution wins within par, and a breadth-first search confirms par is the true minimum.
  • Two levels cannot be crossed without waiting: Wait for the ebb and Spring tide. In Wait for the ebb, hurrying is refused as under-water.
  • Each refusal and its reason, the loss line with its tick, the win line on, under and over par, and restart.
  • The rules don't mutate the state they are given.

Choices to look at

  • wait never refuses for a covered stone. It drowns you, because that is the only way to be "caught by the tide". move refuses covered stones, so it can never drown you.
  • Ticks used counts waits as well as moves, and par is stated in ticks.
  • I did not run the repo's scripts/gate.ts or scripts/fast.ts, because the clone has neither. bun x tsc --noEmit printed only its help text, since the repo has no tsconfig. No dependencies were added.
Approved

Rules module is pure, small, and does what #328 asks; the tests cover every rule and the BFS check that par is the true minimum is a good guard. Verified by reading: the stated solutions hold against the tide table, and loss is reachable in real play (level 1: step onto the height-2 stone, then wait). No page or catalogue entry yet, which the issue scopes out. Next two things: (1) build the playable page and catalogue entry on these rules so the game is reachable; (2) make the test title 'the shore is never covered in the stated levels' true by asserting it, or rename it, and drop the unused let s / L in the tests.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs