97 lines
2.1 KiB
TypeScript
97 lines
2.1 KiB
TypeScript
import {Part} from "./part";
|
|
|
|
export type PartTemplate<TMeta = {}> = Omit<Partial<Part<TMeta>>, 'id'> & TMeta;
|
|
|
|
export type PartPool<TMeta = {}> = {
|
|
parts: Record<string, 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 partsArray = createParts(template, count, idPrefix);
|
|
const parts: Record<string, Part<TMeta>> = {};
|
|
for (const part of partsArray) {
|
|
parts[part.id] = part;
|
|
}
|
|
const available = [...partsArray];
|
|
|
|
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 allPartsArray = pools.flatMap(p => Object.values(p.parts));
|
|
const allParts: Record<string, Part<TMeta>> = {};
|
|
for (const part of allPartsArray) {
|
|
allParts[part.id] = part;
|
|
}
|
|
const template = pools[0].template;
|
|
const available = allPartsArray.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;
|
|
},
|
|
};
|
|
}
|