UNPKG

hathora-et-labora-game

Version:

Game logic reducer for Uwe Rosenberg's Ora et Labora

55 lines (49 loc) 1.85 kB
import { always, curry, identity, pipe, reduce, view } from 'ramda' import { P, match } from 'ts-pattern' import { activeLens, getCost, payCost, withActivePlayer } from '../board/player' import { costPoints, parseResourceParam, rewardCostOptions } from '../board/resource' import { Cost, GameState, StateReducer, TableauReducer, Tile } from '../types' import { LANDSCAPES, forestLocations, moorLocations } from '../board/landscape' // TODO: refactor this with houseOfTheBrotherhood const countForestsAndMoors: (landscape: readonly Tile[][]) => number = reduce( (accum: number, row: Tile[]) => accum + reduce( (accum: number, [, erection]: Tile) => (erection && LANDSCAPES.includes(erection) ? accum + 1 : accum), 0, row ), 0 ) const checkPointsForMoorsAndForests = (output: Cost): TableauReducer => (player) => { if (player === undefined) return undefined const forestsAndMoors = countForestsAndMoors(player.landscape) if (costPoints(output) > forestsAndMoors) return undefined return player } export const festivalGround = (input = '', output = ''): StateReducer => { const inputBeer = parseResourceParam(input) const outputPoints = parseResourceParam(output) if (inputBeer.beer !== 1) return identity return withActivePlayer( pipe( // payCost(inputBeer), checkPointsForMoorsAndForests(outputPoints), getCost(outputPoints) ) ) } export const complete = curry((partial: string[], state: GameState): string[] => { const player = view(activeLens(state), state) return match(partial) .with([], () => { if (player.beer) return ['Be', ''] return [''] }) .with([P._], () => rewardCostOptions(forestLocations(player).length + moorLocations(player).length)) .with([P._, P._], always([''])) .otherwise(always([])) })