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
JavaScript
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