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.

123 lines (119 loc) 4.87 kB
import { assoc, equals, isNotNil, lensPath, pathSatisfies, pipe, set, union, when } from 'ramda' import { match } from 'ts-pattern' import { PlayerColor, SettlementCost, SettlementEnum, SettlementRound, StateReducer } from '../types' import { withEachPlayer } from './player' export const costForSettlement = (settlement: SettlementEnum): SettlementCost => match<SettlementEnum, SettlementCost>(settlement) .with( SettlementEnum.ShantyTownR, SettlementEnum.ShantyTownG, SettlementEnum.ShantyTownB, SettlementEnum.ShantyTownW, () => ({ food: 1, energy: 1 }) ) .with( SettlementEnum.FarmingVillageR, SettlementEnum.FarmingVillageG, SettlementEnum.FarmingVillageB, SettlementEnum.FarmingVillageW, () => ({ food: 3, energy: 3 }) ) .with( SettlementEnum.MarketTownR, SettlementEnum.MarketTownG, SettlementEnum.MarketTownB, SettlementEnum.MarketTownW, () => ({ food: 7, energy: 0 }) ) .with( SettlementEnum.FishingVillageR, SettlementEnum.FishingVillageG, SettlementEnum.FishingVillageB, SettlementEnum.FishingVillageW, () => ({ food: 8, energy: 3 }) ) .with( SettlementEnum.ArtistsColonyR, SettlementEnum.ArtistsColonyG, SettlementEnum.ArtistsColonyB, SettlementEnum.ArtistsColonyW, () => ({ food: 5, energy: 1 }) ) .with(SettlementEnum.HamletR, SettlementEnum.HamletG, SettlementEnum.HamletB, SettlementEnum.HamletW, () => ({ food: 5, energy: 6, })) .with(SettlementEnum.VillageR, SettlementEnum.VillageG, SettlementEnum.VillageB, SettlementEnum.VillageW, () => ({ food: 15, energy: 9, })) .with( SettlementEnum.HilltopVillageR, SettlementEnum.HilltopVillageG, SettlementEnum.HilltopVillageB, SettlementEnum.HilltopVillageW, () => ({ food: 30, energy: 3 }) ) .exhaustive() export const roundSettlements = (color: PlayerColor, round?: SettlementRound): SettlementEnum[] => match<[PlayerColor, SettlementRound | undefined], SettlementEnum[]>([color, round]) .with([PlayerColor.Red, SettlementRound.S], () => [ SettlementEnum.ShantyTownR, SettlementEnum.FarmingVillageR, SettlementEnum.MarketTownR, SettlementEnum.FishingVillageR, ]) .with([PlayerColor.Green, SettlementRound.S], () => [ SettlementEnum.ShantyTownG, SettlementEnum.FarmingVillageG, SettlementEnum.MarketTownG, SettlementEnum.FishingVillageG, ]) .with([PlayerColor.Blue, SettlementRound.S], () => [ SettlementEnum.ShantyTownB, SettlementEnum.FarmingVillageB, SettlementEnum.MarketTownB, SettlementEnum.FishingVillageB, ]) .with([PlayerColor.White, SettlementRound.S], () => [ SettlementEnum.ShantyTownW, SettlementEnum.FarmingVillageW, SettlementEnum.MarketTownW, SettlementEnum.FishingVillageW, ]) .with([PlayerColor.Red, SettlementRound.A], () => [SettlementEnum.ArtistsColonyR]) .with([PlayerColor.Green, SettlementRound.A], () => [SettlementEnum.ArtistsColonyG]) .with([PlayerColor.Blue, SettlementRound.A], () => [SettlementEnum.ArtistsColonyB]) .with([PlayerColor.White, SettlementRound.A], () => [SettlementEnum.ArtistsColonyW]) .with([PlayerColor.Red, SettlementRound.B], () => [SettlementEnum.HamletR]) .with([PlayerColor.Green, SettlementRound.B], () => [SettlementEnum.HamletG]) .with([PlayerColor.Blue, SettlementRound.B], () => [SettlementEnum.HamletB]) .with([PlayerColor.White, SettlementRound.B], () => [SettlementEnum.HamletW]) .with([PlayerColor.Red, SettlementRound.C], () => [SettlementEnum.VillageR]) .with([PlayerColor.Green, SettlementRound.C], () => [SettlementEnum.VillageG]) .with([PlayerColor.Blue, SettlementRound.C], () => [SettlementEnum.VillageB]) .with([PlayerColor.White, SettlementRound.C], () => [SettlementEnum.VillageW]) .with([PlayerColor.Red, SettlementRound.D], () => [SettlementEnum.HilltopVillageR]) .with([PlayerColor.Green, SettlementRound.D], () => [SettlementEnum.HilltopVillageG]) .with([PlayerColor.Blue, SettlementRound.D], () => [SettlementEnum.HilltopVillageB]) .with([PlayerColor.White, SettlementRound.D], () => [SettlementEnum.HilltopVillageW]) .otherwise(() => []) export const introduceSettlements: StateReducer = (state) => { return pipe( // withEachPlayer( when(isNotNil, (player) => assoc( 'settlements', union(player.settlements, roundSettlements(player.color, state?.frame.settlementRound)), player ) ) ), (state) => { if (state === undefined) return state if (state.config.players !== 1) return state return set(lensPath(['players', 1, 'settlements']), [], state) } )(state) }