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.

99 lines 4.03 kB
import { createShuffle } from 'fast-shuffle'; import { createPcg32, randomInt } from 'fn-pcg'; import { pipe, range } from 'ramda'; import { nextFrame } from '../board/frame'; import { districtPrices, makeLandscape, plotPrices } from '../board/landscape'; import { clergyForColor } from '../board/player'; import { GameStatusEnum, NextUseClergy, PlayerColor, SettlementRound, } from '../types'; // we could get more entropy with a second seed, but // honestly this is fine for now. const PCG_PERIOD = 42069; // this is a brute-forced seed given the above, which // results in a noop shuffle for 2, 3, 4, or even 5 elements const MAGIC_SEED = 2692; const neutralColor = (notThisColor, neutralColorIndex) => [ // pick a color that the player isn't using PlayerColor.Red, PlayerColor.Blue, PlayerColor.Green, PlayerColor.White, ].filter((c) => c !== notThisColor)[neutralColorIndex]; export const start = (state, { seed, colors }) => { if (state.rondel === undefined) return undefined; if (state.config === undefined) return undefined; if (colors.length < 1 || colors.length > 4) return undefined; const seedUsed = seed !== null && seed !== void 0 ? seed : MAGIC_SEED; let randGen = createPcg32({}, seedUsed, PCG_PERIOD); const [playerOrderSeed, randGen1] = randomInt(0, 2 ** 32 - 1, randGen); randGen = randGen1; const shuffledColors = createShuffle(playerOrderSeed, colors); const playerIndexes = range(0, state.config.players); const players = playerIndexes.map((i) => { return { landscapeOffset: 0, wonders: 0, peat: 0, penny: 0, clay: 0, wood: 0, grain: 0, sheep: 0, stone: 0, flour: 0, grape: 0, nickel: 0, malt: 0, coal: 0, book: 0, ceramic: 0, whiskey: 0, straw: 0, meat: 0, ornament: 0, bread: 0, wine: 0, beer: 0, reliquary: 0, color: shuffledColors[i], landscape: makeLandscape(shuffledColors[i]), clergy: clergyForColor(state.config)(shuffledColors[i]), settlements: [], }; }); // feels weird to do this here, but i think it's more difficult to pass along the // neutral player's color IF we had it and generate it later from addNeutralPlayer if (state.config.players === 1) { if (seed === undefined) { players.push(Object.assign(Object.assign({}, players[0]), { color: shuffledColors[1], landscape: [[]], clergy: [] })); } else { const [neutralColorIndex, randGen2] = randomInt(0, 3, randGen); randGen = randGen2; const color = neutralColor(players[0].color, neutralColorIndex); players.push(Object.assign(Object.assign({}, players[0]), { color, landscape: [[]], clergy: [] })); } } const newState = Object.assign(Object.assign({}, state), { config: state.config, randGen: randGen1, status: GameStatusEnum.PLAYING, players, rondel: Object.assign(Object.assign({}, state.rondel), { grain: 0, peat: 0, sheep: 0, clay: 0, coin: 0, wood: 0, joker: 0 }), wonders: 8, frame: { next: 1, round: 1, startingPlayer: 0, settlementRound: SettlementRound.S, currentPlayerIndex: 0, activePlayerIndex: 0, neutralBuildingPhase: false, bonusRoundPlacement: false, mainActionUsed: false, bonusActions: [], canBuyLandscape: true, unusableBuildings: [], usableBuildings: [], nextUse: NextUseClergy.Any, }, buildings: [], plotPurchasePrices: plotPrices(state.config), districtPurchasePrices: districtPrices(state.config) }); return pipe( // nextFrame)(newState); }; //# sourceMappingURL=start.js.map