Ice Palace - #481
Ice Palace#481samtcifihi wants to merge 23 commits into
Conversation
The rules require the builder to use the maximum possible number of Yard pyramids, a number the tabletop rules leave to player agreement because searching the possibilities by hand is impractical. Computing it exactly is cheap, because founding is unbounded: a stack founded next to a stack of colour c is itself topped by c, so it chains outwards forever. The problem reduces to which colours can be got onto an outward-facing top, which is a small search over (enabled colours, open large tops, open medium tops). The plan is replayed against the real building code and the achieved length is what gets reported, so the number is always one the builder can reach. Over-estimating would wedge the build phase; under-estimating only relaxes it. Cross-checked against exhaustive search over every legal build order for 45 combinations of Palace shape and Yard contents. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
Three to six players compete to win hands into a temporary common Yard, and
the winner of each hand builds what they won into the permanent Ice Palace,
whose size rule runs opposite to the Yard's. Scores come from whoever owns
the pyramid on top of each Palace stack.
Extends GameBaseSequenced: the winner of a hand passes to close it and then
acts again to build, so one seat acts twice before the seat cycle completes.
Notable rules decisions, all recorded in comments:
- Stacking ignores colour, per "Any color pyramid may be added to a stack
if it is bigger than the current top pyramid". The French translation's
"de la couleur d'un joueur" is a translation artifact.
- A new stack must match one adjacent top, not all of them, per "adjacent
to any existing stack ... the same color as the adjacent top pyramid".
- Adjacency is orthogonal, per the rules' own grid illustration.
- A hand ends on as many consecutive passes as there are players, so the
last placer gets the option to extend rather than close.
- The rules never say how the first pyramid enters an empty Palace, so it
goes anywhere.
- Replenishing is checked per size, since draws are made by size.
- Building never auto-commits; the builder decides who scores what and
wants to rearrange before it becomes permanent.
Hands are public. The rules never address concealment either way, and it is
a presentation decision that does not touch state or legality.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
Covers the game description and name, the validation messages for both building codes and the build-minimum prompts, the sidebar statuses, and the place/remove move-log lines. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
The Yard and the Ice Palace are both unbounded grids that have to be visible at once, which no single bounded board style supports. Freespace places them side by side, each padded by a ring of empty cells so there is somewhere to click when founding a stack on the frontier. Stacks are drawn bottom to top with each pyramid rising slightly above the one below, so the true order is readable. That matters here because the Yard stacks bigger over smaller and the Palace does the reverse, and a nesting convention would read one of them backwards. Freespace reports board clicks as continuous coordinates rather than grid indices, so handleClick inverts the same layout; clicks on a drawn pyramid carry their own cell id instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
Verified against the real renderer for the first time, which turned up two
defects that typechecking alone could not:
- Freespace coordinates are in the renderer's own cellsize units, and
pieces are scaled to it. The layout used 1 unit per cell instead of 50,
so every glyph drew at roughly its native size and the whole canvas came
out as one black rectangle.
- Rows are now pitched further apart than columns. A full three-pyramid
stack rises two risers above its cell, which at the old pitch overlapped
whatever stood in the row above.
Board labels are structured render labels resolved by the front end rather
than English baked into the engine.
Confirmed by rendering a position through the real FreespaceRenderer: the
Palace stacks read large to small upward and the Yard reads small to large,
so the two opposite size rules are visually distinguishable, and Black and
White are legible against the board.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
Two changes, both about matching house style. Volcano's look comes from the `pyramid-flat-*` glyphs, which are the side-on triangle with size pips along the base, not `pyramid-up-*`, which is the top-down square with an X through it. Switching over reads far better here, and it makes the two building codes obvious at a glance: a Palace stack tapers upward while a Yard stack is top-heavy. Those glyphs carry no full-cell sizing box, so the renderer normalises all three sizes to the same footprint and small, medium and large come out identical. Scaling each legend entry back to the true Icehouse height ratios restores the distinction. The rules helpers and build solver move into icepalace.ts, and the two test files become one, since splitting a game across modules is not the norm here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
A player holding only a small Black has no legal placement and must pass, and that happens often. The front drives both auto-passing and the Pass button off the enumerated move list, so declaring no-moves suppressed the list and left those players typing "pass" by hand every time. Hands enumerate cheaply, so the flag was only ever needed for the build phase. Builds are still not enumerated, but rather than offer a single worked build in the move dropdown, where it would read as the only legal arrangement, the build phase offers nothing to pick from and is entered by clicking. Choosing the arrangement is the point of the phase. randomMove supplies a real build so bots and random play keep working. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
…idebar Freespace is not needed here. One stacking-3D squares board carries both structures: the Palace on the left and, while a hand is being played, the Yard to its right, each padded by a ring of empty cells so founding has somewhere to click. During the build the Yard has already been taken up into the stock, so only the Palace is on the board. Coordinate labels are hidden, since the two regions do not share a coordinate space. The current player's hand, or the builder's stock, is a pieces area, which is where a pyramid is picked from; every hand is also listed in the status panel as pyramids. That replaces the player-stashes mechanism. Board clicks now arrive as grid row and column, which map back through the same layout the render uses. Clicking a pyramid in the pieces area yields a bare pyramid id; validation previously rejected anything without a target cell, so a selection could never survive as a partial move. Both phases now accept a trailing bare pyramid as a partial move and prompt for a space. Verified by rendering through the renderer's public entry point, which also validates the JSON against its schema. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
Legend keys double as SVG element ids, and the renderer later looks them up
with querySelector("#" + key). A pyramid id such as "1M" starts with a digit,
which is not a valid selector in a real browser; svgdom accepted it, so the
headless render passed and only a Chromium render exposed it. Keys now carry
a letter prefix, and clicks from the pieces area, which hand back the key,
accept it with or without the prefix.
Verified by rendering the position in Chromium through the renderer's own
playground harness, which also confirmed the pieces area draws below the
board with the current player's owner mark and hand.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
The -3D pyramid glyphs are drawn for Volcano's nests: all three sizes share an apex and grow downward from it, so a medium's base sits 15 units lower than a small's and a large's 30 lower. Volcano lists nests small-first and its default rise of 0.15 exactly cancels those depths, which is why its stacks look planted. Ice Palace stacks pyramids on one another, with a large at the bottom of every Palace tower, so the bottom piece sat up to 30 units low in its cell. Each size now carries a legend nudge that lifts it by its extra depth, so the bottom of any stack sits on the cell centre whatever its size. With bases aligned, the default rise would leave every apex in a stack coincident and the piece drawn last would paint over the tips below it; a rise of 0.25 keeps each tip visible without pulling a stack apart into separate pieces. Checked in Chromium against lone pyramids of each size and both stacking orders, and against Volcano's own playground example. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
The previous fix nudged each size up to stand on the cell and widened the rise to 0.25 so tips would not coincide. That was a compromise: a single rise cannot suit both a medium on a small and a small on a large, so pieces either floated or overlapped a little. Volcano does not tune the rise at all. It spends "-" placeholders, which the renderer skips but still counts, so that with the default rise of 0.15 one array index is exactly one glyph step: a small's base sits on the cell at index 0, a medium's at index 1, a large's at index 2, and their heights are one, two and three steps. A piece whose base should sit `top` steps up goes at index `top + height - 1`. stackColumn lays every stack out that way, so a Palace tower is ["-", "-", L, "-", M, S] and a Yard stack [S, "-", M, "-", "-", L], each pyramid standing on the apex of the one below it in either order, and a lone large is ["-", "-", L]. The nudges are gone and the rise is pinned to 0.15, which the layout depends on. Verified in Chromium against both stacking orders and lone pyramids of every size, and pinned by a test on the emitted columns. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
The previous layout lifted each pyramid by the full height of the one beneath it, so a medium over a large sat three rise-steps up and tips ended up thirty units apart, which read as gaps. Volcano's rule is simpler: each piece sits one index above the last, and "-" placeholders are spent only to keep a base from sinking below the ground. A small stands on the cell at index 0, a medium at index 1 and a large at index 2, so a tower of large, medium, small is ["-", "-", L, M, S] and a Yard stack of small, medium, large needs no placeholders at all. Tips nest fifteen units apart, with no gaps, matching Volcano's own positions. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
The board already grew and shrank with the structures each render, but it did so after every single placement. stacking-3D refits its perspective to the board's width and height, so each change of shape moved every piece, and the Yard, which starts empty every hand, lurched from one cell to three to four over the first few placements. Each structure's region now always covers a five-cell box centred on the origin, where the first pyramid goes, so a structure can grow in any direction for a while before the board changes shape, and past that the board grows only in the direction the structure did. With the ring of padding that gives a 7x7 floor for the Palace alone during the build, and 16x7 during a hand with two empty columns between the Palace and the Yard. A click anywhere in an empty region places the lead at the origin, keeping it in the middle. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
A pyramid picked from the hand or stock now marks every cell it could legally go. The renderer's own dots annotation is not projected onto the stacking-3D board, so each mark is a small glyph placed where the pyramid would land instead. The status panel puts a button, a plain piece in the seventh colour, in front of the hand of whoever leads the current hand. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
The front draws a status-panel glyph from its `glyph` field, as Catapult and Entropy supply it, not from a legend glyph's `name`. The hands and the button were using the legend shape and would have drawn blank. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
The "expanding" display uses the stacking-expanding renderer: the board is seen from above, each stack's pyramids drawn translucently over one another, and hovering a cell lays its stack out beside the board through renderColumn. That renderer draws no pieces area, so the current hand, or the stock during the build, is offered below the board as a local stash of nests, one per colour. The board keeps the same footprint and padding as the perspective display, and the legal-cell dots work in both. Rotation is turned off for both displays with custom-rotation, since neither renderer can turn the board and the front would otherwise offer buttons that do nothing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
…lainly When a hand ends, the event log now says who builds, how many pyramids that takes, and one legal way to build them, quoted so it can be pasted into the move box. The build messages state the computed maximum without qualification; validation keeps accepting that many or more, in case an arrangement the solver did not find exists. The move log moves to the structured collector, and an implementation note records the at-least-one matching neighbour decision and how White and Black match. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
|
You're going mad with power! 🤪 Will take a look when I can. |
|
Please do not edit the |
Reverts the seeded "Ice Palace" names in de, fr, it and es-US and their locale-src sidecars, as requested in review. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
|
I'll send a commit with those things removed and update the instructions I'm giving Claude to avoid them. EDIT: that should be the above commit |
|
A couple more points, with my insertions in square brackets. Only the first one is essential. The rest are recommendations. Once the first one is fixed, I'll merge and you can test on Dev. Thanks for tackling this! Gaps and risks
Recommendation: Mirror morphos.ts: throw VALIDATION_FAILSAFE when
[You may skip this for now if you like. We have a larger issue where generated records have more
[I'm happy to do this when I merge.] |
|
I'll tackle those in couple of hours once my usage limits in Claude reset. That will be more valuable long term for me submitting PRs with less problems in the future than if you just fixed them now. |
move() now throws VALIDATION_FAILSAFE when a non-partial move validates as incomplete, as Morphos does. The build announcement is excluded from published records while staying in the chat log. Adds the BGG id, and tests for the sequenced turn model and record export, a full serialized round trip mid-build with Map revival, and the failsafe. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
Lists the BoardGameGeek page and the archived original rules alongside the Icehouse wiki entry, and credits the implementer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Wtg37k4AQMgCQjK1fHuuy
https://play.abstractplay.com/feedback/f500ada0-da37-4902-a4bc-9d6a294f5a89