- shared/protocol.ts: TurnResult.unowned (keys released this turn) + the map presentation contract (regionFillStyle / unownedTooltipLabel, hue-less grey) - shared/types.ts: required GameState.unowned (cumulative mid-game releases; [] at init, distinct from preset-unassigned regions) - server/engine.ts: applyTurnResult applies releases first (sole-owner only, never fabricating no man's land from unassigned keys), then claims against the post-release snapshot (gain on an ownerless key = re-claim); lone release is isMeaningful; prompts + user payload carry the unowned field - server/stub.ts: unchanged behavior (never releases; e2e stays stable) - server/db.ts: legacy rows load with unowned defaulted to [] - server/index.ts: create-game sets []; jump reference table includes released keys so the model can name them for re-claim - WorldMap/App: unowned prop -> visible grey + 'No man's land' tooltip - unit tests: 105 -> 127 (release/re-claim suites, presentation contract, legacy-row normalization)
26 lines
1.2 KiB
TypeScript
26 lines
1.2 KiB
TypeScript
// Build the choropleth payload from a GameState: every region key (see
|
|
// public/region-keys.json) maps to its owning nation plus that nation's stable
|
|
// color (see shared.nationColor). The client merges this onto the sub-national
|
|
// regions.geo.json (resolving each feature by its own region key) and calls
|
|
// source.setData(). Format-agnostic: it maps whatever keys sit in territory.
|
|
//
|
|
// A key ABSENT from the returned map is unowned (no nation's territory holds
|
|
// it) — this covers both regions a preset never assigned and regions released
|
|
// to no man's land mid-game (v0.22, #16 P3). The map deliberately does NOT
|
|
// distinguish the two: the visible no-man's-land grey vs the faint
|
|
// preset-unassigned look is decided by the client from `GameState.unowned`
|
|
// (see shared/protocol.ts's regionFillStyle).
|
|
import { nationColor, type RegionMap } from '../shared/protocol';
|
|
import type { GameState } from '../shared/types';
|
|
|
|
export function buildRegionMap(state: GameState): RegionMap {
|
|
const map: RegionMap = {};
|
|
for (const [id, nation] of Object.entries(state.nations)) {
|
|
const color = nationColor(id);
|
|
for (const key of nation.territory) {
|
|
map[key] = { color, owner: nation.name, ownerId: id };
|
|
}
|
|
}
|
|
return map;
|
|
}
|