UNPKG

hathora-et-labora-game

Version:

Game logic reducer for Uwe Rosenberg's Ora et Labora

70 lines 3.1 kB
import { always, any, pipe, view } from 'ramda'; import { P, match } from 'ts-pattern'; import { activeLens, withActivePlayer } from '../board/player'; import { BuildingEnum, GameCommandEnum, } from '../types'; import { standardSesourceGatheringAction, updateToken, withRondel } from '../board/rondel'; import { checkNotBonusRound, oncePerFrame } from '../board/frame'; import { forestLocations, forestLocationsForCol } from '../board/landscape'; import { shortGameBonusProduction } from '../board/resource'; const removeForestAt = (row, col) => withActivePlayer((player) => { const tile = player.landscape[row + player.landscapeOffset][col + 2]; if (tile === undefined) return undefined; const [land, building] = tile; if (building !== BuildingEnum.Forest) return undefined; const landscape = [ ...player.landscape.slice(0, row + player.landscapeOffset), [ ...player.landscape[row + player.landscapeOffset].slice(0, col + 2), // the tile in question [land], ...player.landscape[row + player.landscapeOffset].slice(col + 2 + 1), ], ...player.landscape.slice(row + player.landscapeOffset + 1), ]; return { ...player, landscape, }; }); const hasAForest = (landscape) => any((landRow) => { return any((tile) => { return tile?.[1] === BuildingEnum.Forest; }, landRow); }, landscape); export const fellTrees = ({ row, col, useJoker }) => pipe( // oncePerFrame(GameCommandEnum.FELL_TREES), checkNotBonusRound, standardSesourceGatheringAction('wood', useJoker), removeForestAt(row, col), withRondel(updateToken('wood', useJoker)), shortGameBonusProduction({ wood: 1 })); export const complete = (state) => (partial) => { const player = view(activeLens(state), state); return (match(partial) .with([], () => { if (checkNotBonusRound(state) === undefined) return []; if (!hasAForest(player.landscape)) return []; if (oncePerFrame(GameCommandEnum.FELL_TREES)(state) === undefined) return []; return [GameCommandEnum.FELL_TREES]; }) .with([GameCommandEnum.FELL_TREES], () => forestLocations(player)) // shouldnt actually ever see this, but i think its important for completeness .with([GameCommandEnum.FELL_TREES, P._], (_, [, c]) => forestLocationsForCol(c, player)) .with([GameCommandEnum.FELL_TREES, P._, P._], (_, [, c, r]) => { const row = Number.parseInt(r, 10) + player.landscapeOffset; const col = Number.parseInt(c, 10) + 2; const tile = player.landscape?.[row]?.[col]; if (tile?.[1] !== BuildingEnum.Forest) return []; const options = []; if (state?.rondel?.wood !== undefined) options.push(''); if (state?.rondel?.joker !== undefined) options.push('Jo'); return options; }) .with([GameCommandEnum.FELL_TREES, P._, P._, 'Jo'], always([''])) .otherwise(always([]))); }; //# sourceMappingURL=fellTrees.js.map