boardgame-core/src/core/part-factory.ts

89 lines
1.9 KiB
TypeScript
Raw Normal View History

import {Part} from "./part";
export type PartTemplate<TMeta = {}> = Omit<Partial<Part<TMeta>>, 'id'> & TMeta;
export type PartPool<TMeta = {}> = {
parts: Part<TMeta>[];
template: PartTemplate<TMeta>;
draw(): Part<TMeta> | undefined;
return(part: Part<TMeta>): void;
remaining(): number;
};
export function createPart<TMeta = {}>(
template: PartTemplate<TMeta>,
id: string
): Part<TMeta> {
return {
regionId: '',
position: [],
...template,
id,
} as Part<TMeta>;
}
export function createParts<TMeta = {}>(
template: PartTemplate<TMeta>,
count: number,
idPrefix: string
): Part<TMeta>[] {
const parts: Part<TMeta>[] = [];
for (let i = 0; i < count; i++) {
parts.push(createPart(template, `${idPrefix}-${i + 1}`));
}
return parts;
}
export function createPartPool<TMeta = {}>(
template: PartTemplate<TMeta>,
count: number,
idPrefix: string
): PartPool<TMeta> {
const parts = createParts(template, count, idPrefix);
const available = [...parts];
return {
parts,
template,
draw() {
return available.pop();
},
return(part: Part<TMeta>) {
part.regionId = '';
part.position = [];
available.push(part);
},
remaining() {
return available.length;
},
};
}
export function mergePartPools<TMeta = {}>(
...pools: PartPool<TMeta>[]
): PartPool<TMeta> {
if (pools.length === 0) {
return createPartPool({} as PartTemplate<TMeta>, 0, 'merged');
}
const allParts = pools.flatMap(p => p.parts);
const template = pools[0].template;
const available = allParts.filter(p => p.regionId === '');
return {
parts: allParts,
template,
draw() {
return available.pop();
},
return(part: Part<TMeta>) {
part.regionId = '';
part.position = [];
available.push(part);
},
remaining() {
return available.length;
},
};
}