Rev 11: the maze has no wall at zero, and moving sectors carry everything
Relocate Sector could never land a sector west or north of the origin — placements the physical game allows by simply sliding the whole map across the table. The coordinate grid still cannot go negative, but now it does not need to: a sector may land at negative coordinates and the whole maze renormalizes, zero-anchoring on both axes (which also pulls the maze snug when the origin corner is vacated, instead of leaving a blank band). The client offers the new landings as ghost slots on every side, verified slot-for-slot against engine truth. The move also closes a real gap: remapState never carried creatures, boobytrap tokens, glue, open safes, or dimensional warp tokens when a sector relocated or rotated — they were left hovering at their old coordinates. Sectors now carry everything standing on them. Both changes ride rules rev 11; older ledgers replay their flaws intact, as replay determinism demands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
53c84ec6cb
commit
73150a89b5
@@ -151,7 +151,8 @@
|
||||
const k = `${c.x},${c.y}`;
|
||||
if (seen.has(k)) continue;
|
||||
seen.add(k);
|
||||
if (c.x < 0 || c.y < 0) continue;
|
||||
// Before rev 11 the grid stopped at zero; newer games renormalize.
|
||||
if (view!.deckRev < 11 && (c.x < 0 || c.y < 0)) continue;
|
||||
if (origins.some((o) => o.x === c.x && o.y === c.y)) continue;
|
||||
const next = origins.map((o, j) => (j === idx ? c : o));
|
||||
if (next.every((o, j) => next.some((p, m) => m !== j && adjacent(o, p)))) out.push(c);
|
||||
|
||||
@@ -45,12 +45,16 @@
|
||||
} = $props();
|
||||
|
||||
const SECTOR = 5;
|
||||
/** Ghost slots can lie beyond the assembled maze; the canvas grows to hold them. */
|
||||
/** Ghost slots can lie beyond the assembled maze — on any side, including
|
||||
* negative coordinates (the maze renormalizes after the landing). The
|
||||
* canvas grows in whichever direction holds them. */
|
||||
const minBx = $derived(Math.min(0, ...(ghostSlots ?? []).map((g) => g.x)) * CELL - 8);
|
||||
const minBy = $derived(Math.min(0, ...(ghostSlots ?? []).map((g) => g.y)) * CELL - 8);
|
||||
const boundsW = $derived(
|
||||
Math.max(view.board.width, ...(ghostSlots ?? []).map((g) => g.x + SECTOR)) * CELL + 16,
|
||||
Math.max(view.board.width, ...(ghostSlots ?? []).map((g) => g.x + SECTOR)) * CELL + 8 - minBx,
|
||||
);
|
||||
const boundsH = $derived(
|
||||
Math.max(view.board.height, ...(ghostSlots ?? []).map((g) => g.y + SECTOR)) * CELL + 16,
|
||||
Math.max(view.board.height, ...(ghostSlots ?? []).map((g) => g.y + SECTOR)) * CELL + 8 - minBy,
|
||||
);
|
||||
|
||||
|
||||
@@ -171,7 +175,7 @@
|
||||
derive one from the viewBox alone and collapses the board to 0x0 inside
|
||||
a max-height flex column. Doubled so CSS max-* caps still govern. -->
|
||||
<svg
|
||||
viewBox={`-8 -8 ${boundsW} ${boundsH}`}
|
||||
viewBox={`${minBx} ${minBy} ${boundsW} ${boundsH}`}
|
||||
width={boundsW * 2}
|
||||
height={boundsH * 2}
|
||||
class="board"
|
||||
|
||||
@@ -132,7 +132,7 @@ class LocalGame {
|
||||
seed,
|
||||
sets: expansion ? ["basic", "expansion1"] : ["basic"],
|
||||
...(colors ? { colors } : {}),
|
||||
deckRev: 10,
|
||||
deckRev: 11,
|
||||
};
|
||||
const { state, events } = createGame(config);
|
||||
this.config = config;
|
||||
|
||||
Reference in New Issue
Block a user