89 lines
1.9 KiB
TypeScript
89 lines
1.9 KiB
TypeScript
|
|
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;
|
||
|
|
},
|
||
|
|
};
|
||
|
|
}
|