big version with draft order and weather cards
This commit is contained in:
@@ -2,6 +2,114 @@ import type { EnergySimulation, GameState, NodeKey, PlayerId, RootBurst, RoundAn
|
||||
import { keyFor, parseKey, shuffleArray } from "./utils";
|
||||
import { buildChildrenMap, buildParentMap } from "./rules-board";
|
||||
|
||||
function getColumnRegion(state: GameState, column: number) {
|
||||
const third = state.config.columns / 3;
|
||||
if (column < third) {
|
||||
return "left";
|
||||
}
|
||||
|
||||
if (column >= state.config.columns - third) {
|
||||
return "right";
|
||||
}
|
||||
|
||||
return "center";
|
||||
}
|
||||
|
||||
function getLeafCounts(state: GameState) {
|
||||
const childrenMap = buildChildrenMap(state);
|
||||
const counts = state.players.map(() => 0);
|
||||
|
||||
Array.from(state.nodes.entries()).forEach(([nodeKey, node]) => {
|
||||
if (!(childrenMap.get(nodeKey)?.length)) {
|
||||
counts[node.ownerId] += 1;
|
||||
}
|
||||
});
|
||||
|
||||
return counts;
|
||||
}
|
||||
|
||||
function applyWeatherEffects(state: GameState, scores: number[], energySimulation: EnergySimulation) {
|
||||
if (state.activeRoundEffects.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const leafCounts = getLeafCounts(state);
|
||||
const childrenMap = buildChildrenMap(state);
|
||||
const tallestLeaves = state.players.map(() => null as number | null);
|
||||
|
||||
Array.from(state.nodes.entries()).forEach(([nodeKey, node]) => {
|
||||
const leafCount = leafCounts[node.ownerId];
|
||||
if (leafCount <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (childrenMap.get(nodeKey)?.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { row } = parseKey(nodeKey);
|
||||
const currentTallest = tallestLeaves[node.ownerId];
|
||||
if (currentTallest === null || row < currentTallest) {
|
||||
tallestLeaves[node.ownerId] = row;
|
||||
}
|
||||
});
|
||||
|
||||
state.activeRoundEffects.forEach((effectId) => {
|
||||
if (effectId === "leaf_surge") {
|
||||
leafCounts.forEach((count, playerId) => {
|
||||
scores[playerId] += count;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (effectId === "branching_season") {
|
||||
leafCounts.forEach((count, playerId) => {
|
||||
scores[playerId] += Math.max(0, count - 1);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (effectId === "tall_reward") {
|
||||
tallestLeaves.forEach((row, playerId) => {
|
||||
if (row !== null) {
|
||||
scores[playerId] += 2;
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (effectId === "wide_reach") {
|
||||
const maxScore = Math.max(...energySimulation.scores);
|
||||
energySimulation.scores.forEach((score, playerId) => {
|
||||
if (score === maxScore && maxScore > 0) {
|
||||
scores[playerId] += 2;
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
energySimulation.columns.forEach((column) => {
|
||||
if (!column.intercepted || column.ownerId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const region = getColumnRegion(state, column.column);
|
||||
if (effectId === "west_light" && region === "left") {
|
||||
scores[column.ownerId] += 1;
|
||||
}
|
||||
if (effectId === "east_light" && region === "right") {
|
||||
scores[column.ownerId] += 1;
|
||||
}
|
||||
if (effectId === "high_noon" && region === "center") {
|
||||
scores[column.ownerId] += 1;
|
||||
}
|
||||
if (effectId === "edge_bloom" && (column.column === 0 || column.column === state.config.columns - 1)) {
|
||||
scores[column.ownerId] += 1;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function buildEnergySimulation(state: GameState): EnergySimulation {
|
||||
const parentMap = buildParentMap(state);
|
||||
const columns = [];
|
||||
@@ -70,6 +178,8 @@ export function buildEnergySimulation(state: GameState): EnergySimulation {
|
||||
}, new Map<NodeKey, RootBurst>());
|
||||
const rootBursts: RootBurst[] = [...rootBurstMap.values()];
|
||||
|
||||
applyWeatherEffects(state, scores, { scores, columns, rootBursts });
|
||||
|
||||
return {
|
||||
scores,
|
||||
columns,
|
||||
|
||||
Reference in New Issue
Block a user