Step 3.6: add fuel cost
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
36bdbf3af0
commit
ace0d8502d
|
|
@ -24,7 +24,7 @@
|
|||
- [x] **Step 3.3 — Location positions.** `src/positions.ts`: heliocentric ecliptic positions (million km) from `astronomy-engine` for Earth, Mars and Jupiter; Moon = Earth + fixed offset; Ceres on a circular orbit.
|
||||
- [x] **Step 3.4 — Route distance.** `src/distance.ts`: `routeDistance(from, to, gameTime)`, straight-line million km.
|
||||
- [x] **Step 3.5 — Travel time.** `src/travel.ts`: `travelTimeGameHours(ship, distance)` = cruise time + overhead.
|
||||
- [ ] Step 3.6 — Fuel cost
|
||||
- [x] **Step 3.6 — Fuel cost.** `src/fuel.ts`: `fuelCost(ship, origin, distance)` = distance × cost per million km × origin launch multiplier.
|
||||
- [ ] Step 3.7 — Range and landing eligibility
|
||||
- [ ] Step 3.8 — Contract model and payout
|
||||
- [ ] Step 3.9 — Contract board generation
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
import type { Location, ShipModel } from "@deadhead/content";
|
||||
|
||||
/** Fuel cost in credits: distance × the ship's cost per million km × the origin's launch multiplier. */
|
||||
export function fuelCost(ship: ShipModel, origin: Location, distanceMillionKm: number): number {
|
||||
return distanceMillionKm * ship.fuelCostPerMillionKm * origin.launchCostMultiplier;
|
||||
}
|
||||
|
|
@ -3,3 +3,4 @@ export * from "./rng";
|
|||
export * from "./positions";
|
||||
export * from "./distance";
|
||||
export * from "./travel";
|
||||
export * from "./fuel";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
import { content } from "@deadhead/content";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { fuelCost, routeDistance } from "../src/index";
|
||||
|
||||
const courier = content.shipModel("courier")!;
|
||||
const earth = content.location("earth")!;
|
||||
const moon = content.location("moon")!;
|
||||
|
||||
describe("fuel cost", () => {
|
||||
it("costs more Earth→Moon than Moon→Earth for the same ship", () => {
|
||||
const t = Date.parse("2100-01-01T00:00:00Z");
|
||||
const distance = routeDistance(earth, moon, t);
|
||||
expect(fuelCost(courier, earth, distance)).toBeGreaterThan(fuelCost(courier, moon, distance));
|
||||
});
|
||||
|
||||
it("scales linearly with distance", () => {
|
||||
expect(fuelCost(courier, earth, 2)).toBe(2 * fuelCost(courier, earth, 1));
|
||||
expect(fuelCost(courier, earth, 10)).toBe(10 * fuelCost(courier, earth, 1));
|
||||
});
|
||||
|
||||
it("matches a hand calculation", () => {
|
||||
// 0.5M km × 200 credits/M km × Earth multiplier 3.
|
||||
expect(fuelCost(courier, earth, 0.5)).toBe(300);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue