35 lines
1.6 KiB
TypeScript
35 lines
1.6 KiB
TypeScript
/// <reference types="node" />
|
|
/**
|
|
* Prints a balance run for both first-purchase policies (plan Step 12.1), then
|
|
* the fuel-to-payout check (CR-018 Step 18.1):
|
|
* pnpm --filter @deadhead/sim balance [worldSeed] [hours]
|
|
*/
|
|
import { MS_PER_HOUR } from "../src/index";
|
|
import { content } from "@deadhead/content";
|
|
import { formatFuelShares, fuelShares } from "./fuel-share";
|
|
import { simulate, type PurchasePolicy } from "./simulate";
|
|
|
|
const worldSeed = Number(process.argv[2] ?? 12345);
|
|
const hours = Number(process.argv[3] ?? 8);
|
|
for (const policy of ["lighter-first", "freighter-first"] as PurchasePolicy[]) {
|
|
const result = simulate({ worldSeed, policy, durationMs: hours * MS_PER_HOUR });
|
|
console.log(`\n=== ${policy} (seed ${worldSeed}) ===`);
|
|
console.log("milestones (real minutes):", result.milestones);
|
|
console.log(
|
|
`tutorial runs ${result.tutorialRuns}, contracts ${result.contractsDelivered}, ` +
|
|
`veteran contracts in first 2 h ${result.veteranContractsFirstSession}, purchases ${result.purchases.join(", ")}`,
|
|
);
|
|
console.log("violations:", result.violations.length);
|
|
for (const v of result.violations.slice(0, 10))
|
|
console.log(` ${v.minute} min ${v.rule} ${v.detail}`);
|
|
console.log("minute credits loan ships pilot levels");
|
|
for (const s of result.samples.filter((_, i) => i % 3 === 0)) {
|
|
console.log(
|
|
`${String(s.minute).padStart(6)} ${String(s.credits).padStart(7)} ${String(s.loanBalance).padStart(6)} ${s.ships} ${s.pilotLevels.join(" ")}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
console.log("\n=== fuel share of median payout, per ship and route (CR-018) ===");
|
|
console.log(formatFuelShares(fuelShares(content)));
|