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.
69 lines • 3.36 kB
JavaScript
import { match, P } from 'ts-pattern';
import { GameCommandEnum, } from './types';
import { parseResourceParam } from './board/resource';
import { build, commit, config, convert, cutPeat, fellTrees, settle, start, use, withLaybrother, withPrior, buyPlot, buyDistrict, workContract, } from './commands';
const PPlot = P.union('MOUNTAIN', 'COAST');
const PDistrict = P.union('HILLS', 'PLAINS');
const PPlayerCount = P.union('1', '2', '3', '4');
const PCountry = P.union('ireland', 'france');
const PLength = P.union('short', 'long');
export const reducer = (state, [command, ...params]) => {
return match([command, params])
.with([GameCommandEnum.COMMIT, []], () => commit(state))
.with([GameCommandEnum.USE, P.array(P.string)], ([_command, [building, ...params]]) => use(building, params)(state))
.with([GameCommandEnum.BUILD, P.array(P.string)], ([_, [building, col, row]]) => build({
building: building,
col: Number.parseInt(col, 10),
row: Number.parseInt(row, 10),
})(state))
.with([GameCommandEnum.CUT_PEAT, P.array(P.string)], ([_, [col, row, useJoker]]) => cutPeat({
col: Number.parseInt(col, 10),
row: Number.parseInt(row, 10),
useJoker: useJoker === 'Jo',
})(state))
.with([GameCommandEnum.FELL_TREES, P.array(P.string)], ([_, [col, row, useJoker]]) => fellTrees({
col: Number.parseInt(col, 10),
row: Number.parseInt(row !== null && row !== void 0 ? row : '', 10),
useJoker: useJoker === 'Jo',
})(state))
.with([GameCommandEnum.WORK_CONTRACT, P.array(P.string)], ([_, [building, paymentGift, withPrior]]) => workContract(building, paymentGift, withPrior === 'WITH_PRIOR')(state))
.with([GameCommandEnum.WITH_PRIOR, []], () => withPrior(state))
.with([GameCommandEnum.WITH_LAYBROTHER, []], () => withLaybrother(state))
.with([GameCommandEnum.BUY_PLOT, [P._, PPlot]], ([_, [y, side]]) => buyPlot({
y: Number.parseInt(y, 10),
side: side,
})(state))
.with([GameCommandEnum.BUY_DISTRICT, [P._, PDistrict]], ([_, [y, side]]) => buyDistrict({
y: Number.parseInt(y, 10),
side: side,
})(state))
.with([GameCommandEnum.CONVERT, [P.select('resources')]], ({ resources }) => convert(parseResourceParam(resources))(state))
.with([GameCommandEnum.SETTLE, P.array(P.string)], ([_, [settlement, col, row, resources]]) => settle({
settlement: settlement,
col: Number.parseInt(col, 10),
row: Number.parseInt(row, 10),
resources,
})(state))
.with([GameCommandEnum.CONFIG, [PPlayerCount, PCountry, PLength]], ([_, [players, country, length]]) => config({
players: Number.parseInt(players, 10),
length: length,
country: country,
})(state))
.with([GameCommandEnum.START, P.array(P.string)], ([_, params]) => {
const seed = Number.parseInt(params[0], 10);
if (Number.isNaN(seed)) {
return start(state, {
seed: undefined,
colors: params,
});
}
return start(state, {
seed,
colors: params.slice(1),
});
})
.otherwise((command) => {
throw new Error(`Unable to parse [${command.join(',')}]`);
});
};
//# sourceMappingURL=reducer.js.map