UNPKG

hathora-et-labora-game

Version:

Plays Uwe Rosenberg's Ora et Labora for the Hathora engine. It reduces a list of moves into a board game state.

58 lines 3.25 kB
import { filter, pipe, view } from 'ramda'; import { P, match } from 'ts-pattern'; import { addErectionAtLandscape } from '../board/erections'; import { clearNeutralBuildingPhase, onlyViaBonusActions } from '../board/frame'; import { checkLandscapeFree, checkLandTypeMatches, erectableLocations, erectableLocationsCol } from '../board/landscape'; import { activeLens, payCost, withActivePlayer } from '../board/player'; import { costEnergy, costFood, parseResourceParam, settlementCostOptions } from '../board/resource'; import { costForSettlement } from '../board/settlements'; import { GameCommandEnum, } from '../types'; const payForSettlement = (settlement, resources) => withActivePlayer(pipe( // (player) => { const { food, energy } = costForSettlement(settlement); if (costEnergy(resources) < energy) return undefined; if (costFood(resources) < food) return undefined; return player; }, payCost(resources))); const removeSettlementFromUnbuilt = (settlement) => withActivePlayer((player) => { if (!player.settlements.includes(settlement)) return undefined; return Object.assign(Object.assign({}, player), { settlements: filter((s) => s !== settlement, player.settlements) }); }); export const settle = ({ row, col, settlement, resources }) => { const input = parseResourceParam(resources); return pipe( // any of these not defined here are probably shared with BUILD onlyViaBonusActions(GameCommandEnum.SETTLE), checkLandscapeFree(row, col, settlement), checkLandTypeMatches(row, col, settlement), payForSettlement(settlement, input), removeSettlementFromUnbuilt(settlement), addErectionAtLandscape(row, col, settlement), clearNeutralBuildingPhase); }; export const complete = (state) => (partial) => { const player = view(activeLens(state), state); return (match(partial) .with([], () => { if (onlyViaBonusActions(GameCommandEnum.SETTLE)(state) === undefined) return []; if (complete(state)([GameCommandEnum.SETTLE]).length === 0) return []; return [GameCommandEnum.SETTLE]; }) .with([GameCommandEnum.SETTLE], () => { return filter((settlement) => { const playerFood = costFood(player); const playerEnergy = costEnergy(player); const { food: requiredFood, energy: requiredEnergy } = costForSettlement(settlement); return playerFood >= requiredFood && playerEnergy >= requiredEnergy; }, view(activeLens(state), state).settlements); }) .with([GameCommandEnum.SETTLE, P._], ([, settlement]) => // Return all the coords which match the terrain for this building... erectableLocations(settlement, player)) .with([GameCommandEnum.SETTLE, P._, P._], ([, settlement, col]) => erectableLocationsCol(settlement, col, player)) .with([GameCommandEnum.SETTLE, P._, P._, P._], ([, settlement, _col, _row]) => settlementCostOptions(costForSettlement(settlement), player)) // TODO: only show '' if the command is ultimately valid .with([GameCommandEnum.SETTLE, P._, P._, P._, P._], ([, settlement, col, row, resources]) => ['']) .otherwise(() => [])); }; //# sourceMappingURL=settle.js.map