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.

280 lines (275 loc) 12.6 kB
import { match } from 'ts-pattern' import { lensPath, set } from 'ramda' import { BuildingEnum, ErectionEnum, LandEnum, SettlementEnum, StateReducer, Tableau, Tile } from '../types' import { withPlayerIndex } from './player' import { isSettlement } from './buildings' export const terrainForErection = (erection: ErectionEnum): LandEnum[] => match(erection) .with(BuildingEnum.Windmill, () => [LandEnum.Coast, LandEnum.Hillside]) .with(BuildingEnum.FalseLighthouse, () => [LandEnum.Coast]) .with(BuildingEnum.HarborPromenade, () => [LandEnum.Coast]) .with(BuildingEnum.Houseboat, () => [LandEnum.Water]) .with(BuildingEnum.GrapevineA, BuildingEnum.GrapevineB, () => [LandEnum.Hillside]) .with(BuildingEnum.DruidsHouse, () => [LandEnum.Hillside]) .with(BuildingEnum.QuarryA, BuildingEnum.QuarryB, () => [LandEnum.Mountain]) .with(BuildingEnum.Shipyard, () => [LandEnum.Coast]) .with(BuildingEnum.Palace, () => [LandEnum.Hillside]) .with(BuildingEnum.Castle, () => [LandEnum.Hillside, LandEnum.Mountain]) .with(BuildingEnum.CoalHarbor, () => [LandEnum.Coast]) .with(BuildingEnum.ShippingCompany, () => [LandEnum.Coast]) .with(BuildingEnum.RoundTower, () => [LandEnum.Hillside]) .with( SettlementEnum.FishingVillageR, SettlementEnum.FishingVillageG, SettlementEnum.FishingVillageB, SettlementEnum.FishingVillageW, () => [LandEnum.Coast] ) .with( SettlementEnum.HilltopVillageR, SettlementEnum.HilltopVillageG, SettlementEnum.HilltopVillageB, SettlementEnum.HilltopVillageW, () => [LandEnum.Hillside] ) .otherwise(() => [LandEnum.Coast, LandEnum.Hillside, LandEnum.Plains]) export const addErectionAtLandscape = (row: number, col: number, erection: ErectionEnum): StateReducer => (state) => withPlayerIndex( state?.frame.neutralBuildingPhase && !isSettlement(erection) ? 1 : state?.frame.activePlayerIndex ?? 0 )((player) => set(lensPath<Tableau, ErectionEnum>(['landscape', row + player.landscapeOffset, col + 2, 1]), erection, player) )(state) export const pointsForBuilding = (building: ErectionEnum): number => match(building) .with(BuildingEnum.Bakery, () => 4) .with(BuildingEnum.CloisterCourtyard, () => 4) .with(BuildingEnum.HarborPromenade, () => 1) .with(BuildingEnum.Market, () => 5) .with(BuildingEnum.PeatCoalKiln, () => 4) .with(BuildingEnum.StoneMerchant, () => 6) .with(BuildingEnum.Windmill, () => 10) .with(BuildingEnum.CloisterGarden, () => 5) .with(BuildingEnum.FuelMerchant, () => 5) .with(BuildingEnum.Priory, () => 4) .with(BuildingEnum.BuildersMarket, () => 6) .with(BuildingEnum.Carpentry, () => 7) .with(BuildingEnum.GrainStorage, () => 3) .with(BuildingEnum.CloisterLibrary, () => 7) .with(BuildingEnum.CloisterWorkshop, () => 7) .with(BuildingEnum.GrapevineA, () => 3) .with(BuildingEnum.Slaughterhouse, () => 8) .with(BuildingEnum.CloisterChapterHouse, () => 2) .with(BuildingEnum.FinancedEstate, () => 4) .with(BuildingEnum.CloisterChurch, () => 12) .with(BuildingEnum.QuarryA, () => 7) .with(BuildingEnum.Shipyard, () => 15) .with(BuildingEnum.Winery, () => 4) .with(BuildingEnum.Inn, () => 4) .with(BuildingEnum.Bathhouse, () => 2) .with(BuildingEnum.ChamberOfWonders, () => 0) .with(BuildingEnum.Castle, () => 15) .with(BuildingEnum.Palace, () => 25) .with(BuildingEnum.ShippingCompany, () => 8) .with(BuildingEnum.TownEstate, () => 6) .with(BuildingEnum.Calefactory, () => 2) .with(BuildingEnum.QuarryB, () => 7) .with(BuildingEnum.GrapevineB, () => 3) .with(BuildingEnum.Dormitory, () => 3) .with(BuildingEnum.ForgersWorkshop, () => 4) .with(BuildingEnum.HouseOfTheBrotherhood, () => 3) .with(BuildingEnum.PrintingOffice, () => 5) .with(BuildingEnum.Sacristy, () => 10) .with(BuildingEnum.Hospice, () => 7) .with(BuildingEnum.PilgrimageSite, () => 2) .with(BuildingEnum.Estate, () => 5) .with(BuildingEnum.Brewery, () => 9) .with(BuildingEnum.FalseLighthouse, () => 5) .with(BuildingEnum.Houseboat, () => 4) .with(BuildingEnum.Malthouse, () => 5) .with(BuildingEnum.SpinningMill, () => 3) .with(BuildingEnum.Cottage, () => 5) .with(BuildingEnum.Granary, () => 2) .with(BuildingEnum.SacredSite, () => 3) .with(BuildingEnum.Scriptorium, () => 3) .with(BuildingEnum.DruidsHouse, () => 6) .with(BuildingEnum.Chapel, () => 10) .with(BuildingEnum.WhiskeyDistillery, () => 6) .with(BuildingEnum.Alehouse, () => 3) .with(BuildingEnum.Locutory, () => 7) .with(BuildingEnum.Portico, () => 2) .with(BuildingEnum.Cooperage, () => 5) .with(BuildingEnum.GrandManor, () => 18) .with(BuildingEnum.Refectory, () => 4) .with(BuildingEnum.FilialChurch, () => 6) .with(BuildingEnum.ForestHut, () => 1) .with(BuildingEnum.CoalHarbor, () => 12) .with(BuildingEnum.Bulwark, () => 8) .with(BuildingEnum.FestivalGround, () => 3) .with(BuildingEnum.RoundTower, () => 6) .with(BuildingEnum.Camera, () => 5) .with(BuildingEnum.Guesthouse, () => 7) .with(BuildingEnum.ClayMoundR, () => 0) .with(BuildingEnum.ClayMoundG, () => 0) .with(BuildingEnum.ClayMoundB, () => 0) .with(BuildingEnum.ClayMoundW, () => 0) .with(BuildingEnum.FarmYardR, () => 0) .with(BuildingEnum.FarmYardG, () => 0) .with(BuildingEnum.FarmYardB, () => 0) .with(BuildingEnum.FarmYardW, () => 0) .with(BuildingEnum.CloisterOfficeR, () => 0) .with(BuildingEnum.CloisterOfficeG, () => 0) .with(BuildingEnum.CloisterOfficeB, () => 0) .with(BuildingEnum.CloisterOfficeW, () => 0) .with(BuildingEnum.Moor, () => 0) .with(BuildingEnum.Forest, () => 0) .with(SettlementEnum.ShantyTownR, () => 0) .with(SettlementEnum.ShantyTownG, () => 0) .with(SettlementEnum.ShantyTownB, () => 0) .with(SettlementEnum.ShantyTownW, () => 0) .with(SettlementEnum.FarmingVillageR, () => 1) .with(SettlementEnum.FarmingVillageG, () => 1) .with(SettlementEnum.FarmingVillageB, () => 1) .with(SettlementEnum.FarmingVillageW, () => 1) .with(SettlementEnum.MarketTownR, () => 2) .with(SettlementEnum.MarketTownG, () => 2) .with(SettlementEnum.MarketTownB, () => 2) .with(SettlementEnum.MarketTownW, () => 2) .with(SettlementEnum.FishingVillageR, () => 4) .with(SettlementEnum.FishingVillageG, () => 4) .with(SettlementEnum.FishingVillageB, () => 4) .with(SettlementEnum.FishingVillageW, () => 4) .with(SettlementEnum.ArtistsColonyR, () => -1) .with(SettlementEnum.ArtistsColonyG, () => -1) .with(SettlementEnum.ArtistsColonyB, () => -1) .with(SettlementEnum.ArtistsColonyW, () => -1) .with(SettlementEnum.HamletR, () => 3) .with(SettlementEnum.HamletG, () => 3) .with(SettlementEnum.HamletB, () => 3) .with(SettlementEnum.HamletW, () => 3) .with(SettlementEnum.VillageR, () => 8) .with(SettlementEnum.VillageG, () => 8) .with(SettlementEnum.VillageB, () => 8) .with(SettlementEnum.VillageW, () => 8) .with(SettlementEnum.HilltopVillageR, () => 10) .with(SettlementEnum.HilltopVillageG, () => 10) .with(SettlementEnum.HilltopVillageB, () => 10) .with(SettlementEnum.HilltopVillageW, () => 10) .exhaustive() export const pointsForDwelling = (building: ErectionEnum): number => match(building) .with(BuildingEnum.Bakery, () => 5) .with(BuildingEnum.CloisterCourtyard, () => 4) .with(BuildingEnum.HarborPromenade, () => 7) .with(BuildingEnum.Market, () => 8) .with(BuildingEnum.PeatCoalKiln, () => -2) .with(BuildingEnum.StoneMerchant, () => 1) .with(BuildingEnum.Windmill, () => 6) .with(BuildingEnum.CloisterGarden, () => 0) .with(BuildingEnum.FuelMerchant, () => 2) .with(BuildingEnum.Priory, () => 3) .with(BuildingEnum.BuildersMarket, () => 1) .with(BuildingEnum.Carpentry, () => 0) .with(BuildingEnum.GrainStorage, () => 4) .with(BuildingEnum.CloisterLibrary, () => 7) .with(BuildingEnum.CloisterWorkshop, () => 2) .with(BuildingEnum.GrapevineA, () => 6) .with(BuildingEnum.Slaughterhouse, () => -3) .with(BuildingEnum.CloisterChapterHouse, () => 5) .with(BuildingEnum.FinancedEstate, () => 6) .with(BuildingEnum.CloisterChurch, () => 9) .with(BuildingEnum.QuarryA, () => -4) .with(BuildingEnum.Shipyard, () => -2) .with(BuildingEnum.Winery, () => 5) .with(BuildingEnum.Inn, () => 6) .with(BuildingEnum.Bathhouse, () => 6) .with(BuildingEnum.ChamberOfWonders, () => 6) .with(BuildingEnum.Castle, () => 7) .with(BuildingEnum.Palace, () => 8) .with(BuildingEnum.ShippingCompany, () => 4) .with(BuildingEnum.TownEstate, () => 5) .with(BuildingEnum.Calefactory, () => 5) .with(BuildingEnum.QuarryB, () => -4) .with(BuildingEnum.GrapevineB, () => 6) .with(BuildingEnum.Dormitory, () => 4) .with(BuildingEnum.ForgersWorkshop, () => 2) .with(BuildingEnum.HouseOfTheBrotherhood, () => 3) .with(BuildingEnum.PrintingOffice, () => 5) .with(BuildingEnum.Sacristy, () => 7) .with(BuildingEnum.Hospice, () => 5) .with(BuildingEnum.PilgrimageSite, () => 6) .with(BuildingEnum.Estate, () => 6) .with(BuildingEnum.Brewery, () => 7) .with(BuildingEnum.FalseLighthouse, () => 5) .with(BuildingEnum.Houseboat, () => 6) .with(BuildingEnum.Malthouse, () => 4) .with(BuildingEnum.SpinningMill, () => 3) .with(BuildingEnum.Cottage, () => 0) .with(BuildingEnum.Granary, () => 3) .with(BuildingEnum.SacredSite, () => 6) .with(BuildingEnum.Scriptorium, () => 5) .with(BuildingEnum.DruidsHouse, () => 6) .with(BuildingEnum.Chapel, () => 8) .with(BuildingEnum.WhiskeyDistillery, () => 5) .with(BuildingEnum.Alehouse, () => 6) .with(BuildingEnum.Locutory, () => 1) .with(BuildingEnum.Portico, () => 6) .with(BuildingEnum.Cooperage, () => 3) .with(BuildingEnum.GrandManor, () => 7) .with(BuildingEnum.Refectory, () => 5) .with(BuildingEnum.FilialChurch, () => 7) .with(BuildingEnum.ForestHut, () => 5) .with(BuildingEnum.CoalHarbor, () => 0) .with(BuildingEnum.Bulwark, () => 6) .with(BuildingEnum.FestivalGround, () => 7) .with(BuildingEnum.RoundTower, () => 9) .with(BuildingEnum.Camera, () => 3) .with(BuildingEnum.Guesthouse, () => 5) .with(BuildingEnum.ClayMoundR, () => 3) .with(BuildingEnum.ClayMoundG, () => 3) .with(BuildingEnum.ClayMoundB, () => 3) .with(BuildingEnum.ClayMoundW, () => 3) .with(BuildingEnum.FarmYardR, () => 2) .with(BuildingEnum.FarmYardG, () => 2) .with(BuildingEnum.FarmYardB, () => 2) .with(BuildingEnum.FarmYardW, () => 2) .with(BuildingEnum.CloisterOfficeR, () => 2) .with(BuildingEnum.CloisterOfficeG, () => 2) .with(BuildingEnum.CloisterOfficeB, () => 2) .with(BuildingEnum.CloisterOfficeW, () => 2) .with(BuildingEnum.Moor, () => 0) .with(BuildingEnum.Forest, () => 0) .with(SettlementEnum.ShantyTownR, () => -3) .with(SettlementEnum.ShantyTownG, () => -3) .with(SettlementEnum.ShantyTownB, () => -3) .with(SettlementEnum.ShantyTownW, () => -3) .with(SettlementEnum.FarmingVillageR, () => 1) .with(SettlementEnum.FarmingVillageG, () => 1) .with(SettlementEnum.FarmingVillageB, () => 1) .with(SettlementEnum.FarmingVillageW, () => 1) .with(SettlementEnum.MarketTownR, () => 2) .with(SettlementEnum.MarketTownG, () => 2) .with(SettlementEnum.MarketTownB, () => 2) .with(SettlementEnum.MarketTownW, () => 2) .with(SettlementEnum.FishingVillageR, () => 6) .with(SettlementEnum.FishingVillageG, () => 6) .with(SettlementEnum.FishingVillageB, () => 6) .with(SettlementEnum.FishingVillageW, () => 6) .with(SettlementEnum.ArtistsColonyR, () => 5) .with(SettlementEnum.ArtistsColonyG, () => 5) .with(SettlementEnum.ArtistsColonyB, () => 5) .with(SettlementEnum.ArtistsColonyW, () => 5) .with(SettlementEnum.HamletR, () => 4) .with(SettlementEnum.HamletG, () => 4) .with(SettlementEnum.HamletB, () => 4) .with(SettlementEnum.HamletW, () => 4) .with(SettlementEnum.VillageR, () => 6) .with(SettlementEnum.VillageG, () => 6) .with(SettlementEnum.VillageB, () => 6) .with(SettlementEnum.VillageW, () => 6) .with(SettlementEnum.HilltopVillageR, () => 8) .with(SettlementEnum.HilltopVillageG, () => 8) .with(SettlementEnum.HilltopVillageB, () => 8) .with(SettlementEnum.HilltopVillageW, () => 8) .exhaustive()