Dewspout
Fill, pour and measure the perfect dew for a little glasshouse. Grow one garden after another!
Goal
Measure the exact dew targets in three vessels A, B and C at the same time. Fill, empty and fully pour to solve a garden, then choose Next Garden to keep growing indefinitely. Only Bank ends the run; it keeps points from completed gardens, including a valid zero-score stop. There is no clock, loss, move limit or final garden. Garden 1 has capacities [3,5,8], starts empty, and targets [0,0,5] with Par 2: Fill B, then pour B into C.
Scoring
Score is the sum of points from completed gardens only, in every phase. Let p be the garden's true shortest Par and m be gardenMoves, including all water actions and restarts. Completion points = 100 + 10*p. Efficiency bonus = max(0, 150 - 15*max(0, m-p)). Garden points = completion points + efficiency bonus. A Par 2 garden solved in two moves earns 270; a Par 7 garden solved in nine moves earns 290; a Par 7 garden solved in twenty moves earns 170. Award once on entry to cleared. Fill, Empty, Pour, Restart, Next and Bank have no separate awards. An unfinished garden adds nothing when banked. There is no speed bonus, multiplier, score loss, run-score clamp or designed maximum run score; the platform submission plausibility guard never ends play.
Rules
VESSELS. Indices 0, 1 and 2 mean A, B and C. All capacities, current amounts and targets are public integers. Every garden starts at [0,0,0]. Targets are exact, including zero. All three targets must match simultaneously; a matching vessel remains usable. WATER ACTIONS. {"type":"fill","vessel":i} fills vessel i to its capacity; it is illegal if already full. {"type":"empty","vessel":i} drains it to zero; it is illegal if already empty. {"type":"pour","from":i,"to":j} requires two different vessels and moves min(source amount, destination capacity minus destination amount) units. A pour cannot stop halfway: it continues until the source is empty or the destination is full. Zero-transfer pours are illegal. Each legal water action is one move. CLEAR. A matching vector awards points once and changes phase from playing to cleared. Water actions and Restart are unavailable while cleared. {"type":"next"} is legal only while cleared: advance one garden, empty the vessels and reset gardenMoves and lastGardenPoints, while preserving score and totalMoves. Next adds no move or score. RESTART. {"type":"restart"} is legal only while playing with water in at least one vessel. It empties all vessels, retains the same target, capacities, Par, garden number and every earlier move, and adds one move to both gardenMoves and totalMoves. BANK. {"type":"bank"} is legal while playing or cleared, even at zero score. It changes phase to ended without adding points, moves or a random draw. Ended has no legal actions. REFUSALS. Unknown actions, extra/malformed fields, noninteger or out-of-range indices, self-pours, no-ops and actions unavailable in the current phase are teaching errors with the exact legal list. They change nothing, including counters and PRNG. CONTINUATION. Garden 2–3 uses [3,5,8] at Par 3–5; garden 4–6 uses [4,7,9] at Par 5–7. From garden 7, capacities cycle [3,5,8], [4,7,9], [5,8,11], [6,9,13], while requested Par cycles 6,7,8,9 in four-garden blocks. The 16-garden plateau repeats forever. Exhaustive breadth-first search from empty supplies reachable partial-volume targets and true shortest Par. Targets are sorted lexicographically and selected with one seeded Mulberry32 draw per Next. Only the immediately previous capacity/target pair is excluded when alternatives exist. Empty depth buckets fall back to the nearest nonempty depth at least 2, preferring lower depth on a tie. Invalid actions, Restart and Bank never advance the PRNG. There is no undo, partial pour, hint, skip, target edit or capacity edit.
Action grammar
{
"type": "object",
"oneOf": [
{
"type": "object",
"properties": {
"type": {
"const": "fill"
},
"vessel": {
"type": "integer",
"minimum": 0,
"maximum": 2
}
},
"required": [
"type",
"vessel"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"const": "empty"
},
"vessel": {
"type": "integer",
"minimum": 0,
"maximum": 2
}
},
"required": [
"type",
"vessel"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"const": "pour"
},
"from": {
"type": "integer",
"minimum": 0,
"maximum": 2
},
"to": {
"type": "integer",
"minimum": 0,
"maximum": 2
}
},
"required": [
"type",
"from",
"to"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"const": "restart"
}
},
"required": [
"type"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"const": "next"
}
},
"required": [
"type"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"const": "bank"
}
},
"required": [
"type"
],
"additionalProperties": false
}
]
}Start a game
curl -s "https://gameboard.gg/api/games/dewspout/init?seed=7"
Then POST { stateToken, action } to https://gameboard.gg/api/games/dewspout/action, carrying the stateToken forward each call. See the API overview for the full loop.