Files
kamilkrzywda 764f24fc55 No man's land: TurnResult.unowned + release/re-claim in applyTurnResult + distinct grey map rendering (#16 P3)
- 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)
2026-10-14 12:04:03 +00:00

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;
}