import {Part} from "./part"; export type PartTemplate = Omit>, 'id'> & TMeta; export type PartPool = { parts: Record>; template: PartTemplate; draw(): Part | undefined; return(part: Part): void; remaining(): number; }; export function createPart( template: PartTemplate, id: string ): Part { const part: Part = { id, regionId: template.regionId ?? '', position: template.position ?? [], ...template, }; return part; } export function createParts( template: PartTemplate, count: number, idPrefix: string ): Part[] { const parts: Part[] = []; for (let i = 0; i < count; i++) { parts.push(createPart(template, `${idPrefix}-${i + 1}`)); } return parts; } export function createPartPool( template: PartTemplate, count: number, idPrefix: string ): PartPool { const partsArray = createParts(template, count, idPrefix); const parts: Record> = {}; for (const part of partsArray) { parts[part.id] = part; } const available = [...partsArray]; return { parts, template, draw() { return available.pop(); }, return(part: Part) { part.regionId = ''; part.position = []; available.push(part); }, remaining() { return available.length; }, }; } export function mergePartPools( ...pools: PartPool[] ): PartPool { if (pools.length === 0) { return createEmptyPartPool(); } const allPartsArray = pools.flatMap(p => Object.values(p.parts)); const allParts: Record> = {}; 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) { part.regionId = ''; part.position = []; available.push(part); }, remaining() { return available.length; }, }; } function createEmptyPartPool(): PartPool { return { parts: {}, template: {} as PartTemplate, draw() { return undefined; }, return(_part: Part) { // no-op for empty pool }, remaining() { return 0; }, }; } export function createPartsFromTable(items: T[], getId: (item: T, index: number) => string, getCount?: ((item: T) => number) | number){ const pool: Record> = {}; for (const entry of items) { const count = getCount ? (typeof getCount === 'function' ? getCount(entry) : getCount) : 1; for (let i = 0; i < count; i++) { const id = getId(entry, i); pool[id] = { id, regionId: '', position: [], ...entry }; } } return pool; }