import { simulate } from "./simulate"; // Event balance by hand (Step 26.9): `tsx balance/measure-events.ts `. const SEEDS = [12345, 777, 4242, 99, 2026, 31337, 8, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14]; const LONG = Number(process.argv[2] ?? 12); const HOURS = Number(process.argv[3] ?? 8); const window = (worldSeed: number, events: "off" | "defaults" | "best", longHaul: number) => simulate({ worldSeed, policy: "lighter-first", durationMs: (6 + HOURS) * 3_600_000, scenario: { atMinute: 300, minutes: HOURS * 60, mode: "active" }, events, eventsFromMinute: 300, longHaulMinGameHours: longHaul, firstEventDone: true, }); const median = (xs: number[]) => [...xs].sort((a, b) => a - b)[Math.floor(xs.length / 2)]!; const r3 = (v: number) => Math.round(v * 1000) / 1000; for (const longHaul of process.argv[4] === "long" ? [LONG] : [0, LONG]) { const rows = SEEDS.map((seed) => { const off = window(seed, "off", longHaul); const def = window(seed, "defaults", longHaul); const best = window(seed, "best", longHaul); const income = Math.max(1, off.scenarioEarnings!); return { seed, trips: def.events.windowTrips, share: r3(def.events.windowWithEvent / Math.max(1, def.events.windowTrips)), good: r3(def.events.good / Math.max(1, def.events.withEvent)), defRun: r3(def.scenarioEarnings! / income), bestRun: r3(best.scenarioEarnings! / income), defValue: r3(1 + def.events.windowDefaultValue / income), bestValue: r3(1 + def.events.windowBestValue / income), hullCost: r3(def.events.windowHullCost / income), repairSpend: r3(def.events.windowRepairSpend / income), violations: def.violations.length, }; }); console.log(`--- longHaul ${longHaul}, ${HOURS} h`); for (const r of rows) console.log(JSON.stringify(r)); const m = (k: keyof (typeof rows)[number]) => r3(median(rows.map((r) => r[k] as number))); console.log( ["share", "good", "defRun", "bestRun", "defValue", "bestValue", "hullCost", "repairSpend"] .map((k) => `${k} ${m(k as keyof (typeof rows)[number])}`) .join(" "), ); }