67 lines
2.6 KiB
TypeScript
67 lines
2.6 KiB
TypeScript
import { content } from "@deadhead/content";
|
||
import { describe, expect, it } from "vitest";
|
||
import { emergencyFuel, fuelPriceAt, tripFuel, type ShipState } from "../src/index";
|
||
|
||
const { config } = content;
|
||
const courier = content.shipModel("courier")!;
|
||
const [earth, moon] = [content.location("earth")!, content.location("moon")!];
|
||
const discoveredIds = new Set(["earth", "moon"]);
|
||
/** A Courier at the Moon: its only discovered way out is Earth. */
|
||
const legToEarth = tripFuel(courier, moon, earth, config);
|
||
const moonPrice = fuelPriceAt(moon, config);
|
||
const atMoon = (fuelFu: number, inFlight = false): ShipState => ({
|
||
id: "s1",
|
||
modelId: "courier",
|
||
locationId: "moon",
|
||
inFlight,
|
||
tank: { fuelFu, avgPrice: moonPrice },
|
||
});
|
||
|
||
describe("emergency fuel (Step 15.5, decision 0.5.99)", () => {
|
||
it("is offered when the tank can't reach anywhere and the credits can't buy the shortfall", () => {
|
||
const offer = emergencyFuel({ ship: atMoon(1), credits: 0, discoveredIds }, content);
|
||
expect(offer).not.toBeNull();
|
||
// Exactly the cheapest leg's fuel minus what is on board, at 2.5 × the local price.
|
||
expect(offer!.amountFu).toBeCloseTo(legToEarth - 1);
|
||
expect(offer!.price).toBeCloseTo(moonPrice * 2.5);
|
||
expect(offer!.cost).toBe(Math.round((legToEarth - 1) * moonPrice * 2.5));
|
||
});
|
||
|
||
it("is not offered when the tank can already reach somewhere", () => {
|
||
expect(
|
||
emergencyFuel({ ship: atMoon(legToEarth), credits: 0, discoveredIds }, content),
|
||
).toBeNull();
|
||
});
|
||
|
||
it("is not offered when the player can afford the fuel", () => {
|
||
const shortfallCost = Math.ceil((legToEarth - 1) * moonPrice);
|
||
expect(
|
||
emergencyFuel({ ship: atMoon(1), credits: shortfallCost, discoveredIds }, content),
|
||
).toBeNull();
|
||
expect(
|
||
emergencyFuel({ ship: atMoon(1), credits: shortfallCost - 1, discoveredIds }, content),
|
||
).not.toBeNull();
|
||
});
|
||
|
||
it("is not offered in flight", () => {
|
||
expect(emergencyFuel({ ship: atMoon(1, true), credits: 0, discoveredIds }, content)).toBeNull();
|
||
});
|
||
|
||
it("covers only the cheapest leg when there are several ways out", () => {
|
||
// From Earth, the Moon is the cheapest leg for a Clipper (Mars costs far more).
|
||
const clipper = content.shipModel("clipper")!;
|
||
const ship: ShipState = {
|
||
id: "s2",
|
||
modelId: "clipper",
|
||
locationId: "earth",
|
||
inFlight: false,
|
||
tank: { fuelFu: 0, avgPrice: 0 },
|
||
};
|
||
const offer = emergencyFuel(
|
||
{ ship, credits: 0, discoveredIds: new Set(["earth", "moon", "mars"]) },
|
||
content,
|
||
);
|
||
expect(offer!.amountFu).toBeCloseTo(tripFuel(clipper, earth, moon, config));
|
||
});
|
||
});
|