This commit is contained in:
2026-04-09 09:00:25 -04:00
parent 5b44762fbb
commit d61b8de6b7
3 changed files with 26 additions and 10 deletions

View File

@@ -63,6 +63,25 @@ let state: GameState = createInitialState(setup);
let isNewGameModalOpen = false;
let previousScoreSnapshot: ScoreSnapshot[] | null = null;
function rebuildSetup(overrides: Partial<SetupState> = {}) {
setup = createSetupState(
overrides.playerCount ?? setup.playerCount,
overrides.columns ?? setup.columns,
overrides.rows ?? setup.rows,
overrides.startingNodesPerPlayer ?? setup.startingNodesPerPlayer,
overrides.sunbeamChance ?? setup.sunbeamChance,
overrides.diseaseChance ?? setup.diseaseChance,
overrides.seedInputs ?? setup.seedInputs,
overrides.paletteOrder ?? setup.paletteOrder,
overrides.initiativeMode ?? setup.initiativeMode,
overrides.biddingOrderRule ?? setup.biddingOrderRule,
overrides.weatherDraftEnabled ?? setup.weatherDraftEnabled,
overrides.winCondition ?? setup.winCondition,
overrides.maxRounds ?? setup.maxRounds,
overrides.topLeafTarget ?? setup.topLeafTarget,
);
}
function getLiveExposureScores() {
return buildEnergySimulation(state).scores;
}
@@ -1307,7 +1326,7 @@ function attachEvents() {
if (output) {
output.textContent = input.value;
}
setup = createSetupState(Number(input.value), setup.columns, setup.rows, setup.startingNodesPerPlayer, setup.sunbeamChance, setup.diseaseChance, setup.seedInputs, setup.paletteOrder, setup.shuffleTurnOrder, setup.initiativeMode, setup.biddingOrderRule, setup.weatherDraftEnabled, setup.winCondition, setup.maxRounds, setup.topLeafTarget);
rebuildSetup({ playerCount: Number(input.value) });
render();
});
document.querySelector<HTMLInputElement>("#column-count")?.addEventListener("change", (event) => {
@@ -1316,7 +1335,7 @@ function attachEvents() {
return;
}
setup = createSetupState(setup.playerCount, Math.max(6, Math.min(24, columns)), setup.rows, setup.startingNodesPerPlayer, setup.sunbeamChance, setup.diseaseChance, setup.seedInputs, setup.paletteOrder, setup.shuffleTurnOrder, setup.initiativeMode, setup.biddingOrderRule, setup.weatherDraftEnabled, setup.winCondition, setup.maxRounds, setup.topLeafTarget);
rebuildSetup({ columns: Math.max(6, Math.min(24, columns)) });
render();
});
document.querySelector<HTMLInputElement>("#row-count")?.addEventListener("change", (event) => {
@@ -1325,7 +1344,7 @@ function attachEvents() {
return;
}
setup = createSetupState(setup.playerCount, setup.columns, Math.max(6, Math.min(24, rows)), setup.startingNodesPerPlayer, setup.sunbeamChance, setup.diseaseChance, setup.seedInputs, setup.paletteOrder, setup.shuffleTurnOrder, setup.initiativeMode, setup.biddingOrderRule, setup.weatherDraftEnabled, setup.winCondition, setup.maxRounds, setup.topLeafTarget);
rebuildSetup({ rows: Math.max(6, Math.min(24, rows)) });
render();
});
document.querySelector<HTMLInputElement>("#starting-nodes")?.addEventListener("change", (event) => {
@@ -1334,7 +1353,7 @@ function attachEvents() {
return;
}
setup = createSetupState(setup.playerCount, setup.columns, setup.rows, Math.max(1, nextValue), setup.sunbeamChance, setup.diseaseChance, setup.seedInputs, setup.paletteOrder, setup.shuffleTurnOrder, setup.initiativeMode, setup.biddingOrderRule, setup.weatherDraftEnabled, setup.winCondition, setup.maxRounds, setup.topLeafTarget);
rebuildSetup({ startingNodesPerPlayer: Math.max(1, nextValue) });
render();
});
document.querySelector<HTMLInputElement>("#sunbeam-chance")?.addEventListener("change", (event) => {

View File

@@ -1,6 +1,6 @@
import { PLAYER_PALETTE, STARTING_POINTS } from "./constants";
import type { GameState, Player, SetupState } from "./types";
import { keyFor, shuffleArray } from "./utils";
import { keyFor } from "./utils";
export function createDefaultPaletteOrder(playerCount: number) {
return Array.from({ length: playerCount }, (_, index) => index % PLAYER_PALETTE.length);
@@ -76,7 +76,6 @@ export function createSetupState(
diseaseChance = 0,
seedInputs: string[] | null = null,
paletteOrder: number[] | null = null,
shuffleTurnOrder = true,
initiativeMode: SetupState["initiativeMode"] = "fixed",
biddingOrderRule: SetupState["biddingOrderRule"] = "rotating",
weatherDraftEnabled = true,
@@ -97,7 +96,6 @@ export function createSetupState(
diseaseChance,
seedInputs: Array.from({ length: playerCount }, (_, index) => seedInputs?.[index] ?? defaults[index]),
paletteOrder: Array.from({ length: playerCount }, (_, index) => paletteOrder?.[index] ?? paletteDefaults[index]),
shuffleTurnOrder,
initiativeMode,
biddingOrderRule,
weatherDraftEnabled,
@@ -164,7 +162,7 @@ export function normalizeSeedInputs(setup: SetupState) {
}
export function createInitialState(setup: SetupState): GameState {
const playerPaletteOrder = setup.shuffleTurnOrder ? shuffleArray(setup.paletteOrder) : [...setup.paletteOrder];
const playerPaletteOrder = [...setup.paletteOrder];
const players = createPlayers(setup.playerCount, playerPaletteOrder);
const turnOrder = players.map((player) => player.id);
const nodes = new Map();
@@ -213,7 +211,7 @@ export function createInitialState(setup: SetupState): GameState {
gameOver: false,
history: [
`Round 1 begins on a ${setup.columns}x${setup.rows} board with ${setup.startingNodesPerPlayer} starting node${setup.startingNodesPerPlayer === 1 ? "" : "s"} each.`,
`${setup.shuffleTurnOrder ? "Turn order was randomized for this game." : "Turn order uses the setup order."}`,
"Turn order uses the setup order unless changed by initiative drafting.",
],
roundSummary: null,
};

View File

@@ -21,7 +21,6 @@ export type SetupState = {
diseaseChance: number;
seedInputs: string[];
paletteOrder: number[];
shuffleTurnOrder: boolean;
initiativeMode: "fixed" | "bid";
biddingOrderRule: "rotating" | "lowest_growth_income";
weatherDraftEnabled: boolean;