UNPKG

hathora-et-labora-game

Version:

Game logic reducer for Uwe Rosenberg's Ora et Labora

104 lines 4.15 kB
import { always, assoc, curry, equals, isNil, pathSatisfies, propSatisfies, when } from 'ramda'; import { match } from 'ts-pattern'; import { ResourceEnum, } from '../types'; import { getCost, withActivePlayer } from './player'; import { multiplyGoods, parseResourceParam } from './resource'; const tokenToResource = (token) => { switch (token) { case 'grain': return ResourceEnum.Grain; case 'sheep': return ResourceEnum.Sheep; case 'clay': return ResourceEnum.Clay; case 'coin': return ResourceEnum.Penny; case 'wood': return ResourceEnum.Wood; case 'peat': return ResourceEnum.Peat; case 'grape': return ResourceEnum.Grape; case 'stone': return ResourceEnum.Stone; } }; export const withRondel = (func) => { return (state) => { if (state === undefined) return state; const rondel = func(state.rondel); if (rondel === undefined) return undefined; return assoc('rondel', rondel, state); }; }; export const updateRondel = (token) => { return (rondel) => { if (rondel === undefined) return undefined; if (rondel[token] === undefined) return rondel; return assoc(token, rondel[token] !== undefined ? rondel.pointingBefore : rondel[token])(rondel); }; }; const introduceToken = (token) => withRondel(when(propSatisfies(isNil, token), (rondel) => assoc(token, rondel.pointingBefore, rondel))); export const introduceGrapeToken = when(pathSatisfies(equals('france'), ['config', 'country']), introduceToken('grape')); export const introduceStoneToken = introduceToken('stone'); export const armValues = ({ length, players }) => { if (players === 2 && length === 'short') { return [0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 10]; } return [0, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10]; }; export const take = (armIndex, tokenIndex, config) => { const armVals = armValues(config); return armVals[(armIndex - tokenIndex + armVals.length) % armVals.length]; }; export const takePlayerJoker = (unitCost) => { return (state) => { if (state === undefined) return undefined; const { pointingBefore, joker } = state.rondel; const config = state.config; const takeValue = take(pointingBefore, joker ?? pointingBefore, config); return withActivePlayer(getCost(multiplyGoods(takeValue)(unitCost)))(state); }; }; export const advanceJokerOnRondel = withRondel((rondel) => rondel && assoc('joker', rondel.pointingBefore, rondel)); export const updateToken = (withToken, withJoker) => (rondel) => { if (withJoker) return updateRondel('joker')(rondel); if (rondel[withToken] === undefined) return updateRondel('joker')(rondel); return updateRondel(withToken)(rondel); }; export const standardSesourceGatheringAction = (usingToken, withJoker) => { return (state) => { if (state === undefined) return state; const { joker, pointingBefore } = state.rondel; const config = state.config; const main = state.rondel[usingToken]; const amount = take(pointingBefore, (withJoker ? joker : (main ?? joker)) ?? pointingBefore, config); const resource = tokenToResource(usingToken); const cost = parseResourceParam(resource); const magnitude = multiplyGoods(amount)(cost); return withActivePlayer(getCost(magnitude))(state); }; }; export const standardSesourceGatheringCompletion = curry((usingToken, partial, state) => { const jokerAvailable = state.rondel.joker !== undefined; const mainAvailable = state.rondel[usingToken] !== undefined; return match(partial) .with([], () => { if (jokerAvailable && mainAvailable) return ['', 'Jo']; if (jokerAvailable !== mainAvailable) return ['']; return []; }) .with(['Jo'], () => (jokerAvailable ? [''] : [])) .otherwise(always([])); }); //# sourceMappingURL=rondel.js.map