//? Is is a good idea? Probably not. interface Recipe { tile?: string, inputs: string[], outputs: string[], action: "instant" | "passive" | "active" duration?: number } const all_items = new Set() function out(r: Recipe) { r.inputs.forEach(i => all_items.add(i)) r.outputs.forEach(i => all_items.add(i)) console.log(`- { tile: ${r.tile ?? null}, inputs: ${JSON.stringify(r.inputs)}, outputs: ${JSON.stringify(r.outputs)}, action: !${r.action + " " + (r.duration ?? "")} }`); } type Component = (e: string) => void const cut = (new_name?: string): Component => e => { out({ action: "active", duration: 2, tile: "cuttingboard", inputs: [e], outputs: [new_name ?? ("sliced-" + e)] }) } const cook = (new_name?: string): Component => e => { const i = e + "-pot" const o = (new_name ?? ("cooked-" + e)) + "-pot" out({ action: "instant", inputs: ["pot", e], outputs: [i] }) out({ action: "passive", duration: 2, tile: "stove", inputs: [i], outputs: [o] }) } const crate: Component = e => out({ action: "instant", tile: e + "-crate", inputs: [], outputs: [e], }) function item(name: string, ...components: Component[]) { for (const f of components) { f(name) } } function combine(container: string, ...inputs: string[]) { const open = inputs.map(i => [i]) while (1) { const e = open.pop() if (!e) break; const cur = e.join("-") + "-" + container for (const i of inputs) { if (e.includes(i)) continue const parts = [...e, i] parts.sort() const o = parts.join("-") + "-" + container if (all_items.has(o)) continue open.push(parts) out({ action: "instant", inputs: [cur, i], outputs: [o] }) } } } item("tomato", cut(), crate, cook("tomato-soop")) combine("plate", "steak", "sliced-tomato", "bread") for (const i of all_items) { const parts = i.split("-"); const container = parts.pop()!; if (parts.length >= 1 && ["pot", "plate"].includes(container)) { out({ action: "instant", tile: "trash", inputs: [i], outputs: [container] }) } else { out({ action: "instant", tile: "trash", inputs: [i], outputs: [] }) } }