Connect automatic unambiguous Jacurutu physical-force income, a sole-occupant Testing Station storm choice and Shrine reciprocal physical card roles to engine actions, player controls, legal AI and saved continuation. Preserve Weather Control exclusion, exact card/force custody, private hand boundaries and committed effects after restart. Shared role checks cover existing ordinary and special Karama paths; reserved cards cannot enter another pending use. Keep Orgiz, mixed-force Jacurutu allocation and contested Cistern/Testing Station benefits explicitly pending. These are bounded prototypes; complete Discovery/Advanced/expansion and publication gates remain closed. Validation: types, lint and 4,345 offline tests passed (32 added), production build passed, and 40 HTTP tests passed. Independent cross-reviews repaired reserved-card deadlock, physical-card selection, alternate-role permission, storm source/token binding and public-entitlement bot ordering. The first broad run found five failures; focused repairs preceded the stable repeated check. Browser A5EJQ2W4 used genuine Discovery setup/reveal/free entry with targeted QA positioning. A human increased storm movement from two to three sectors, moving sector 6 to 9. Refresh restored station forces and the private Snooper. This was targeted control/recovery evidence, not an unmodified full game. All 187 opening saved rooms remained unchanged; 31 QA/HTTP rooms were added (218 total). Reused the running server; no restart or save reset. Source-bound report: /home/quintine/.local/share/dune/checkpoints/20260913-discovery-location-effects/verification-final/report.json Source fingerprint: beecb85ab7ec39319115389c115434d161591e8549802c542a6343a0fc19bea6 Durations: check 140540ms; build 6741ms; integration 24956ms. Aggregate goal counter 63,116,444 to 64,295,091 at final verification: 1,178,647 tokens before final Git/push overhead for three bounded functions. Standing authorization: Push all from now on.
26 lines
782 B
TypeScript
26 lines
782 B
TypeScript
import type { Action, GameView } from './engine';
|
|
|
|
/** Both human controls and bots use only the owner's projected storm offer. */
|
|
export function discoveryStormActions(game: GameView): Action[] {
|
|
const decision = game.decision,
|
|
offer = game.ecologicalStorm;
|
|
if (
|
|
game.status !== 'playing' ||
|
|
decision?.kind !== 'ecologicalStorm' ||
|
|
decision.player !== game.me ||
|
|
!offer ||
|
|
offer.owner !== game.me ||
|
|
offer.event !== decision.event ||
|
|
offer.blocked
|
|
)
|
|
return [];
|
|
// Keeping the ordinary movement is the conservative first prototype policy.
|
|
return [...offer.options]
|
|
.sort((a, b) => Math.abs(a.delta) - Math.abs(b.delta))
|
|
.map((option) => ({
|
|
type: 'decision',
|
|
event: offer.event,
|
|
delta: option.delta,
|
|
}));
|
|
}
|