Baskmere
Little turtles climb onto big ones. Stack the pond turtles into their sunny spots before the daylight runs out!
Goal
Baskmere is an endless ladder of sorting ponds. Each pond has a row of 3 to 5 basking rocks and pond turtles numbered by size, 1 the smallest. Every pond shows a plan, a full target layout of which turtles each rock should hold. Move turtles one at a time until every pile matches the plan, then drift on to the next pond. Every move spends Daylight, and each pond grants exactly enough for its par (the true minimum, found by exhaustive search) plus a spare that shrinks as you travel. Unused Daylight carries forward. The run ends when the Daylight left can no longer settle the current pond, or when you send END_RUN. Points are only ever added: nothing you earned is ever taken back. Precise play can continue indefinitely; there is no last pond.
Scoring
Higher is better. Score is awarded only when a pond is settled. raw = 20 * par + 10 * min(pond, 60). Grade: spent equal to par is Perfect, spent up to par + 2 is Tidy, anything more is Settled; spending less than par is impossible. A Perfect pond multiplies raw by 3/2 (rounded down). The streak rises by 1 on Perfect, holds on Tidy and resets to 0 on Settled, and is applied after that update as a multiplier of (100 + 25 * min(streak, 8)) percent, so 100 percent at streak 0 up to 300 percent. award = floor((raw * multiplier percent + 50) / 100), added to the score. Example: pond 4 with par 7 finished Perfect while the streak rises from 3 to 4 gives raw (140 + 40) * 3 / 2 = 270 and an award of 540. END_RUN and sunset never subtract. The per pond ceiling is par 32 at the depth cap, Perfect, at the capped streak; the plausibility guard for a whole run is 1000000.
Rules
THE TWO TURTLE RULES: only the top turtle of a pile can move, and a turtle may only be placed on an empty rock or on a turtle bigger than itself, so every pile is always ordered biggest at the bottom. ROCKS are indexed 0 to P - 1 from left to right, and the rightmost rock is the Sun Rock. Ponds have 3, 4 or 5 rocks and 3 to 9 turtles; state.pond.turtles[size - 1] describes each turtle and every pile in state.piles and state.pond.plan is listed bottom to top. THE PLAN (state.pond.plan) is the full target layout for this pond and never changes; the pond settles the moment every pile equals it. DAYLIGHT: { "type": "MOVE", "from": a, "to": b } moves the top turtle of rock a onto rock b and costs 1 Daylight, or 2 when the moving turtle is the Grandshell. STEP_BACK performs the inverse of your last move and costs the same Daylight as a move; it never refunds. A mistake plus its step back therefore costs twice. PAR AND SPARE: each pond adds par + spare to your Daylight when it opens. spare is 8 on ponds 1 and 2 and falls by 1 every 2 ponds to a floor of 0, reached at pond 17, after which a pond grants exactly its par. Settling a pond at exactly par (Perfect) adds a Sunbeam of 1 Daylight to your carry. SUNSET: after every MOVE or STEP_BACK that does not settle the pond, if the weighted Daylight needed to reach the plan from the current piles is more than the Daylight you have, the run ends immediately. A move that settles the pond with 0 Daylight left still settles. LAST LIGHT: if after a move the Daylight needed exactly equals the Daylight you have, the report sets lastLight true; from then on every move must be a shortest path move. This is the only live distance hint. POND FEATURES, introduced one at a time and then combined: a LILY PAD (from pond 7) is a rock that holds at most 2 turtles and is never the Sun Rock; SHY SHELLS (from pond 11) forbid placing a turtle directly on a turtle with the same shell colour, while an empty rock is always allowed; the CREEK (from pond 15) makes rocks 0, 1, 2 a one way loop where a turtle may only swim 0 to 1, 1 to 2 and 2 to 0, state.pond.lanes[from][to] is false for every closed lane, and a STEP_BACK against the current is refused; the GRANDSHELL (from pond 19) is the biggest turtle and each of its moves costs 2 Daylight, and par counts those weights. Later ponds combine drawn features, and from pond 60 every feature the rock count allows appears together. Some combinations are never drawn because they leave too few legal moves: a 3 rock pond after pond 20 never has a lily pad and never has the creek together with shy shells, so it carries at most the Grandshell plus the creek or shy shells; a 4 rock pond never has the creek, a lily pad and shy shells together, so it carries at most three; a 5 rock pond can carry all four. Every pond is checked in advance so that every position you can reach can still reach the plan: the only way to lose a pond is Daylight. PHASES: in phase pond the legal actions are MOVE, STEP_BACK and END_RUN; once a pond settles the phase is drift, where only NEXT_POND and END_RUN are legal; in runOver nothing is legal. END_RUN at the drift is a win, END_RUN mid pond is a good game, and nothing is ever forfeited either way. An illegal action comes back as { ok: false, reason, legalActions } with the state untouched and no Daylight spent; getLegalActions lists exactly the legal set, MOVEs first in from then to order. Nothing is hidden apart from the random cursor that shapes future ponds.
Action grammar
{
"type": "object",
"oneOf": [
{
"type": "object",
"properties": {
"type": {
"const": "MOVE",
"description": "Move the top turtle of rock `from` onto rock `to`. Costs 1 Daylight, or 2 for the Grandshell."
},
"from": {
"type": "integer",
"minimum": 0,
"maximum": 4,
"description": "The rock to lift the top turtle from, 0 is leftmost. Must exist in this pond and hold a turtle."
},
"to": {
"type": "integer",
"minimum": 0,
"maximum": 4,
"description": "The rock to set the turtle down on. It must be empty or have a bigger top turtle, and respect lily pads, shy shells and the creek."
}
},
"required": [
"type",
"from",
"to"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"const": "STEP_BACK",
"description": "Undo the last move by performing its inverse. Costs the same Daylight as that move and never refunds."
}
},
"required": [
"type"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"const": "NEXT_POND",
"description": "Open the next pond, adding its par plus spare to your Daylight. Legal only at the drift."
}
},
"required": [
"type"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"const": "END_RUN",
"description": "End the run and keep every point. A win at the drift, a good game mid pond."
}
},
"required": [
"type"
],
"additionalProperties": false
}
]
}Start a game
curl -s "https://gameboard.gg/api/games/baskmere/init?seed=7"
Then POST { stateToken, action } to https://gameboard.gg/api/games/baskmere/action, carrying the stateToken forward each call. See the API overview for the full loop.