Central banks now redeem the national money foreign banks hold, sell reserves to defend a weak rate, and cover part of strategic imports from reserves. Five repeatable technologies raise each commodity's output per unit of energy. Hostile troops on a road or sea lane sever trade, power and unit supply. Middlemen buy food to resell to neighbours at a markup, and starving regions buy before those topping up their buffers, which clears the landlocked famines. The economic map's trade graph gains a colour legend.
44 lines
1.8 KiB
JavaScript
44 lines
1.8 KiB
JavaScript
import { TestCase } from "./framework/test_case.js";
|
|
import { smallState, cityOf } from "./framework/helpers.js";
|
|
import { RESOURCE_IDS, MIDDLEMAN } from "../shared/data.js";
|
|
import { foodNeedPerDay } from "../shared/resources.js";
|
|
|
|
export class FoodSecurityTest extends TestCase {
|
|
test_starving_regions_buy_before_stocked_ones() {
|
|
const state = smallState();
|
|
const cities = state.cities.filter((city) => city.civ === 0);
|
|
this.assertGreater(cities.length, 1, "the fixture has two regions");
|
|
const starving = cities[0];
|
|
const stocked = cities[1];
|
|
state.getCityResourceStock(starving).food = 0;
|
|
state.getCityResourceStock(stocked).food =
|
|
foodNeedPerDay(state.getCityEconomy(stocked).population) * 5;
|
|
const order = [];
|
|
const orig = state._procureFromNeighbours.bind(state);
|
|
state._procureFromNeighbours = function (city, ...rest) {
|
|
order.push(city.id);
|
|
return orig(city, ...rest);
|
|
};
|
|
const market = new Map(RESOURCE_IDS.map((id) => [
|
|
id, { supply: 0, demand: 0, price: state.getResourcePrice(id) },
|
|
]));
|
|
state._consumeCityResources(new Map(), market);
|
|
this.assertEqual(order[0], starving.id, "the empty region buys first");
|
|
}
|
|
|
|
test_a_middleman_charges_a_margin_on_relayed_food() {
|
|
const state = smallState();
|
|
const city = cityOf(state, 0);
|
|
state._relayStock.set(city.id, 100);
|
|
const price = state.getResourcePrice("food");
|
|
const supplier = { kind: "city", city };
|
|
const markup = state._middlemanMarkup(supplier, "food", 60, price);
|
|
this.assertApprox(markup, 60 * price * MIDDLEMAN.markup);
|
|
this.assertApprox(state._relayStock.get(city.id), 40, 1e-9, "only the sold stock is drawn");
|
|
this.assertEqual(
|
|
state._middlemanMarkup(supplier, "steel", 10, price), 0,
|
|
"only food carries the margin"
|
|
);
|
|
}
|
|
}
|