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
JavaScript
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