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.
84 lines • 3.7 kB
JavaScript
import { curry, dropLast, head, last, map, pipe, reduce, splitAt, splitEvery, startsWith, take, view, without, } from 'ramda';
import { P, match } from 'ts-pattern';
import { activeLens, getCost, withActivePlayer } from '../board/player';
import { BuildingEnum } from '../types';
import { forestLocations, forestLocationsForCol } from '../board/landscape';
const removeForestAt = (player, [col, row]) => {
if (player === undefined)
return undefined;
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 Object.assign(Object.assign({}, player), { landscape });
};
export const printingOffice = (...coords) => {
if (coords.length % 2 === 1)
return () => undefined;
const pairs = take(4)(splitEvery(2)(map((n) => Number.parseInt(n, 10), coords)));
return withActivePlayer(pipe(
//
(state) => reduce(removeForestAt, state, pairs), getCost({ book: pairs.length })));
};
const forestPairs = (player) => (coords) => {
const forestsAlreadyCutDown = pipe(
//
splitEvery(2), map(([a, b]) => `${a} ${b}`))(coords);
const forestsRemaining = pipe(
//
forestLocations, without(forestsAlreadyCutDown))(player);
return [...forestsRemaining, ''];
};
const forestPairsWithColumn = (player) => (coords) => {
const coordPairs = splitEvery(2, coords);
const completePairs = dropLast(1, coordPairs);
const forestsCutDown = map(([a, b]) => `${a} ${b}`, completePairs);
const allForestsRemaining = forestLocations(player);
const forestsAfterCutDown = without(forestsCutDown, allForestsRemaining);
const coordsAvail = reduce((accum, coordPair) => {
var _a;
const col = (_a = last(coords)) !== null && _a !== void 0 ? _a : '';
if (startsWith(`${col} `, coordPair)) {
const [, row] = splitAt(col.length + 1, coordPair);
accum.push(row);
}
return accum;
}, [], forestsAfterCutDown);
return coordsAvail;
};
// TODO: this can be better
export const complete = curry((partial, state) => {
const player = view(activeLens(state), state);
return match(partial)
.with([], forestPairs(player))
.with([P._], (coords) => { var _a; return forestLocationsForCol((_a = head(coords)) !== null && _a !== void 0 ? _a : '', player); })
.with([P._, P._], forestPairs(player))
.with([P._, P._, P._], forestPairsWithColumn(player))
.with([P._, P._, P._, P._], forestPairs(player))
.with([P._, P._, P._, P._, P._], forestPairsWithColumn(player))
.with([P._, P._, P._, P._, P._, P._], forestPairs(player))
.otherwise((param) => {
const locations = param;
if ((locations === null || locations === void 0 ? void 0 : locations.length) === 7) {
// well this is annoying, i can't check an array with more than 6 things?
return forestPairsWithColumn(player)(locations);
}
if ((locations === null || locations === void 0 ? void 0 : locations.length) === 8) {
return [''];
}
return [];
});
});
//# sourceMappingURL=printingOffice.js.map