40 lines
1.4 KiB
JavaScript
40 lines
1.4 KiB
JavaScript
import { GOODS, BASE_PRICE, TYPICAL_STOCK, MAX_STOCK } from './constants.js';
|
|
|
|
// Deterministic price curve: scarce -> expensive. Clamped to [0.25x, 4x].
|
|
// Always pass the raw float planet.stock[good]; never reconstruct price from
|
|
// the floored integer stock shown in marketView rows.
|
|
export function priceOf(good, stock) {
|
|
const ratio = TYPICAL_STOCK / Math.max(stock, 1);
|
|
const mult = Math.min(4, Math.max(0.25, ratio));
|
|
return Math.round(BASE_PRICE[good] * mult * 100) / 100;
|
|
}
|
|
|
|
// Lazily advance a planet's stocks to time t (no per-tick simulation).
|
|
export function advancePlanet(planet, t) {
|
|
const dt = t - planet.stockTime;
|
|
if (dt <= 0) return;
|
|
for (const g of GOODS) {
|
|
const rate = (planet.produces[g] || 0) - (planet.consumes[g] || 0);
|
|
planet.stock[g] = Math.min(MAX_STOCK, Math.max(0, planet.stock[g] + rate * dt));
|
|
}
|
|
planet.stockTime = t;
|
|
}
|
|
|
|
// Execute a trade at the current price. deltaQty > 0 delivers goods,
|
|
// deltaQty < 0 removes them. Returns the unit price the trade executed at.
|
|
export function applyTrade(planet, t, good, deltaQty) {
|
|
advancePlanet(planet, t);
|
|
const price = priceOf(good, planet.stock[good]);
|
|
planet.stock[good] = Math.min(MAX_STOCK, Math.max(0, planet.stock[good] + deltaQty));
|
|
return price;
|
|
}
|
|
|
|
export function marketView(planet, t) {
|
|
advancePlanet(planet, t);
|
|
return GOODS.map((g) => ({
|
|
good: g,
|
|
stock: Math.floor(planet.stock[g]),
|
|
price: priceOf(g, planet.stock[g]),
|
|
}));
|
|
}
|