Expand the board to the full sketch (~107 spaces, three forks)
shared/board.js now transcribes every distinct space label from the hand-drawn sketch (assets/game_board.png) rather than Phase 1's small subset. The sketch's arrows get genuinely ambiguous in a few places (it reads as a mockup, not an engineered spec) and reuses several space names across zones (Start A Business, Family Reunion, Market Crash, ...) — that repetition is kept as intentional flavor rather than deduplicated, and the ambiguous bits are resolved into a clean DAG with the same shape Phase 1 proved out: a fork, a chain() per branch, a convergence — repeated three times (Career/Education/Gap Year, then Relationship/Investment, then High Risk/Safe), into a long shared retirement tail. Branches are built with a small chain() helper that auto-wires each entry's `next` to the following one, since hand-wiring ~107 ids was too error-prone. The reducer, SQLite schema, and rooms/WS layer needed zero changes — the whole point of the pure-reducer/graph-data design from Phase 1. Two things did need generalizing: - public/boardRender.js's lane offset was hardcoded to a 2-way fork; the new "Which Path?" fork is 3-way (Career/Education/Gap Year), so the offset formula is now symmetric for any number of branches. - shared/game.test.js hardcoded Phase 1's specific space ids. Rewritten to be board-structure-agnostic: it always resolves the first offered choice and otherwise rolls the max die value, which reliably makes progress regardless of board shape (walkForward always stops early at the next choice/finish), plus a graph-well-formedness check. Verified: unit tests green; a full two-player game played headlessly end-to-end through all three forks to Finish in 38 turns with zero console/page errors; the rendered board visually confirmed at full scale (5-row snake layout, 3-way fork fans out correctly, all labels legible).
This commit is contained in:
+10
-8
@@ -10,7 +10,7 @@ const SVG_NS = 'http://www.w3.org/2000/svg';
|
||||
|
||||
const COL_WIDTH = 108;
|
||||
const ROW_HEIGHT = 168;
|
||||
const LANE_HEIGHT = 52;
|
||||
const LANE_HEIGHT = 64;
|
||||
const MARGIN_X = 70;
|
||||
const MARGIN_Y = 80;
|
||||
const NODE_W = 88;
|
||||
@@ -26,7 +26,7 @@ const TYPE_STYLE = {
|
||||
};
|
||||
|
||||
/** Pure layout computation — no DOM. Returns { positions, edges, width, height }. */
|
||||
export function computeLayout(board, colsPerRow = 9) {
|
||||
export function computeLayout(board, colsPerRow = 14) {
|
||||
const ids = Object.keys(board.spaces);
|
||||
const outEdges = new Map(ids.map((id) => [id, []]));
|
||||
const predecessors = new Map(ids.map((id) => [id, []]));
|
||||
@@ -53,12 +53,14 @@ export function computeLayout(board, colsPerRow = 9) {
|
||||
children.forEach((childId, i) => {
|
||||
col.set(childId, Math.max(col.get(childId) ?? -Infinity, col.get(id) + 1));
|
||||
|
||||
// Choice spaces fan their two branches out (-1/+1 lanes); anything else
|
||||
// just inherits the parent's lane unchanged. A join (>1 predecessor)
|
||||
// accumulates every incoming contribution and averages once all of its
|
||||
// predecessors have been processed (guaranteed by the time `remaining`
|
||||
// hits 0, since that only happens after every in-edge is visited).
|
||||
const offset = space.type === 'choice' ? (i === 0 ? -1 : 1) : 0;
|
||||
// Choice spaces fan their N branches out symmetrically around the
|
||||
// parent's lane (works for 2-way, 3-way, ... forks alike); anything
|
||||
// else just inherits the parent's lane unchanged. A join (>1
|
||||
// predecessor) accumulates every incoming contribution and averages
|
||||
// once all of its predecessors have been processed (guaranteed by the
|
||||
// time `remaining` hits 0, since that only happens after every
|
||||
// in-edge is visited).
|
||||
const offset = space.type === 'choice' ? i - (children.length - 1) / 2 : 0;
|
||||
const contribution = laneSum.get(id) + offset;
|
||||
laneSum.set(childId, (laneSum.get(childId) ?? 0) + contribution);
|
||||
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@
|
||||
|
||||
/* --- Board --- */
|
||||
.board-container {
|
||||
overflow-x: auto; border-radius: 14px; margin-bottom: 14px;
|
||||
overflow: auto; max-height: 620px; border-radius: 14px; margin-bottom: 14px;
|
||||
background: radial-gradient(900px 500px at 30% 0%, #2a5f4c 0%, #1d493c 55%, #163a30 100%);
|
||||
border: 1px solid var(--line);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user