Public: anyone can read this; the crew can change it.
Migrated from github.com/amirmushichge/pixel-plays
Milk Churns rules: a tested `milk-churns/churns.js` where you pour milk between three churns to leave an exact amount within par, in a two-file pull with a test file that runs in under a second #353
Check · Review · Land · Live done — Landed and live in production.
This adds the Milk Churns rules in `milk-churns/churns.js` and `milk-churns/churns.test.mjs`, and nothing else. `bun test milk-churns/churns.test.mjs` passes: 11 tests, 412 assertions, 43 ms (under the one-second limit).
shipped production is serving it deploy 5b5fb07
This adds the Milk Churns rules in milk-churns/churns.js and milk-churns/churns.test.mjs, and nothing else. bun test milk-churns/churns.test.mjs passes: 11 tests, 412 assertions, 43 ms (under the one-second limit).
What changed
- Levels: there are seven in
LEVELS, each with a name, three capacities, the starting fill (largest churn full, the others empty), a target in litres and a stated solution. Par is the solution's length. Every solution is a shortest one, found by breadth-first search, and par runs from 2 to 8 pours. - Functions:
start,pour,undo,restartanddescribeare plain data in, plain data out, with no DOM, timers or randomness. The module exports likepumpkin-patch/plots.js:module.exports, or aMilkChurnsglobal for the page. - Pouring: a pour moves
min(source, target space)litres, so the total milk never changes. The level is won when any churn holds exactly the target. - Refusals: each returns the same state and a reason:
unknown-churn,same-churn,empty-source,full-target,nothing-to-undoorgame-over. - Undo after a win:
undois still allowed once the level is won, as in Pumpkin Patch. - Win line: it reads like "You win: 2 L left in a churn in 2 pours against par 2, at par", with "under par" or "N over par" otherwise.
Tests: besides the checks you listed, the tests check that every level's starting fill is the largest churn full and that start falls back to level 0 for an unknown level.
Not done
- No page and no catalogue entry, as the issue says.
- The "under par" win line is tested on a state whose par I raised by hand. Every solution is already a shortest one, so no real level can be won under par.
Checks not run
scripts/gate.ts: it doesn't exist in this clone, so the gate didn't run.bun x tsc --noEmit: it only printed its help text because the clone has no tsconfig, so it checked nothing.
To try it: run bun test milk-churns/churns.test.mjs.
Rules module and tests as the issue asks; I re-ran a breadth-first search over all seven levels and every stated solution is a true shortest one (par 2,2,3,4,6,6,8). Nothing is served yet, so there is no page to judge for phone/keyboard/no-JS; that is the next pull's job. Two things I would do next: (1) the page pull should announce refusals and the win line in an aria-live region and wording for a person, mapping the reason codes (empty-source, full-target, ...) to plain sentences rather than showing them raw; (2) since no real level can be won under par, consider adding a level whose stated solution is deliberately longer than a shortest one, or document par as 'shortest' in the README, so the 'under par' line is reachable by play and not only by a hand-made state.
Left #332 open: 1 unticked item remain (milk-churns/churns.test.mjs asserts each rule above. It checks that each level's stated solution wins within par, that a pour stops at an empty source and at a full target, and that total milk is conserved after every pour. It also checks each refusal with its reason, that undo restores the exact previous state, the win line at, under and over par, and restart.).
This adds the Milk Churns rules in
milk-churns/churns.jsandmilk-churns/churns.test.mjs, and nothing else.bun test milk-churns/churns.test.mjspasses: 11 tests, 412 assertions, 43 ms (under the one-second limit).What changed
LEVELS, each with a name, three capacities, the starting fill (largest churn full, the others empty), a target in litres and a stated solution. Par is the solution's length. Every solution is a shortest one, found by breadth-first search, and par runs from 2 to 8 pours.start,pour,undo,restartanddescribeare plain data in, plain data out, with no DOM, timers or randomness. The module exports likepumpkin-patch/plots.js:module.exports, or aMilkChurnsglobal for the page.min(source, target space)litres, so the total milk never changes. The level is won when any churn holds exactly the target.unknown-churn,same-churn,empty-source,full-target,nothing-to-undoorgame-over.undois still allowed once the level is won, as in Pumpkin Patch.Tests: besides the checks you listed, the tests check that every level's starting fill is the largest churn full and that
startfalls back to level 0 for an unknown level.Not done
Checks not run
scripts/gate.ts: it doesn't exist in this clone, so the gate didn't run.bun x tsc --noEmit: it only printed its help text because the clone has no tsconfig, so it checked nothing.To try it: run
bun test milk-churns/churns.test.mjs.Closes #332