UNPKG

hathora-et-labora-game

Version:

Game logic reducer for Uwe Rosenberg's Ora et Labora

38 lines 2.54 kB
import { add, always, ap, concat, curry, map, min, multiply, pipe, range, reverse, unnest, view } from 'ramda'; import { P, match } from 'ts-pattern'; import { activeLens, getCost, payCost, withActivePlayer } from '../board/player'; import { canAfford, costEnergy, energyCostOptions, parseResourceParam, stringRepeater } from '../board/resource'; export const bakery = (param = '') => { // parse the input string and create variables for each resource, defaulting to 0 if none const { flour = 0, wood = 0, coal = 0, straw = 0, peat = 0, bread = 0 } = parseResourceParam(param); // total up all the energy, divide by 1/2, and if they are sending in more flour than that if (flour > costEnergy({ wood, coal, straw, peat }) / 0.5) return always(undefined); return withActivePlayer(pipe( // make sure the player has this much stuff (for bread, reduce that amount by the number of flour) canAfford({ flour, wood, coal, straw, peat, bread: bread - flour }), // remove all of the stuff from the player, except bread payCost({ flour, wood, coal, straw, peat }), // then give them n bread, where n is the amount of flour getCost({ bread: flour }), // then take away how many breads they sent in as input payCost({ bread }), // and give them 4 coins per bread getCost({ penny: (Math.min(bread, 2) * 4) % 5, nickel: Math.floor((Math.min(bread, 2) * 4) / 5) }))); }; export const complete = curry((partial, state) => match(partial) .with([], () => { const player = view(activeLens(state), state); const { flour = 0, wood = 0, coal = 0, straw = 0, peat = 0, bread = 0 } = player; // step 1: figure out how many times we might send in flour, given flour and energy constraint const flourAmounts = pipe(costEnergy, multiply(2), Math.ceil, min(flour), add(1), range(0), (reverse))(player); // step 2: for each amount of flour to use up, multiply by ways of getting that energy const paymentAmounts = unnest(map((flourAmount) => map((s) => [bread + flourAmount, s], ap([concat(stringRepeater('Fl', flourAmount))], energyCostOptions(flourAmount / 2, { coal, peat, wood, straw }))), flourAmounts)); const consumeBreadAmounts = unnest(map(([sellableBread, resourceString]) => pipe( // min(2), add(1), range(0), (reverse), ap([stringRepeater('Br')]), map((s) => resourceString + String(s)))(sellableBread), paymentAmounts)); return consumeBreadAmounts; }) .with([P._], always([''])) .otherwise(always([]))); //# sourceMappingURL=bakery.js.map