hathora-et-labora-game
Version:
Game logic reducer for Uwe Rosenberg's Ora et Labora
70 lines • 3.1 kB
JavaScript
import { always, any, pipe, view } from 'ramda';
import { P, match } from 'ts-pattern';
import { activeLens, withActivePlayer } from '../board/player';
import { BuildingEnum, GameCommandEnum, } from '../types';
import { standardSesourceGatheringAction, updateToken, withRondel } from '../board/rondel';
import { checkNotBonusRound, oncePerFrame } from '../board/frame';
import { forestLocations, forestLocationsForCol } from '../board/landscape';
import { shortGameBonusProduction } from '../board/resource';
const removeForestAt = (row, col) => withActivePlayer((player) => {
const tile = player.landscape[row + player.landscapeOffset][col + 2];
if (tile === undefined)
return undefined;
const [land, building] = tile;
if (building !== BuildingEnum.Forest)
return undefined;
const landscape = [
...player.landscape.slice(0, row + player.landscapeOffset),
[
...player.landscape[row + player.landscapeOffset].slice(0, col + 2),
// the tile in question
[land],
...player.landscape[row + player.landscapeOffset].slice(col + 2 + 1),
],
...player.landscape.slice(row + player.landscapeOffset + 1),
];
return {
...player,
landscape,
};
});
const hasAForest = (landscape) => any((landRow) => {
return any((tile) => {
return tile?.[1] === BuildingEnum.Forest;
}, landRow);
}, landscape);
export const fellTrees = ({ row, col, useJoker }) => pipe(
//
oncePerFrame(GameCommandEnum.FELL_TREES), checkNotBonusRound, standardSesourceGatheringAction('wood', useJoker), removeForestAt(row, col), withRondel(updateToken('wood', useJoker)), shortGameBonusProduction({ wood: 1 }));
export const complete = (state) => (partial) => {
const player = view(activeLens(state), state);
return (match(partial)
.with([], () => {
if (checkNotBonusRound(state) === undefined)
return [];
if (!hasAForest(player.landscape))
return [];
if (oncePerFrame(GameCommandEnum.FELL_TREES)(state) === undefined)
return [];
return [GameCommandEnum.FELL_TREES];
})
.with([GameCommandEnum.FELL_TREES], () => forestLocations(player))
// shouldnt actually ever see this, but i think its important for completeness
.with([GameCommandEnum.FELL_TREES, P._], (_, [, c]) => forestLocationsForCol(c, player))
.with([GameCommandEnum.FELL_TREES, P._, P._], (_, [, c, r]) => {
const row = Number.parseInt(r, 10) + player.landscapeOffset;
const col = Number.parseInt(c, 10) + 2;
const tile = player.landscape?.[row]?.[col];
if (tile?.[1] !== BuildingEnum.Forest)
return [];
const options = [];
if (state?.rondel?.wood !== undefined)
options.push('');
if (state?.rondel?.joker !== undefined)
options.push('Jo');
return options;
})
.with([GameCommandEnum.FELL_TREES, P._, P._, 'Jo'], always(['']))
.otherwise(always([])));
};
//# sourceMappingURL=fellTrees.js.map