diff --git a/components/shared/ProducingGraph/ProducingGraph.tsx b/components/shared/ProducingGraph/ProducingGraph.tsx index cc6d9b3..8e3431f 100644 --- a/components/shared/ProducingGraph/ProducingGraph.tsx +++ b/components/shared/ProducingGraph/ProducingGraph.tsx @@ -18,29 +18,9 @@ export const ProducingGraph = ,>({nodes, inputs, outputs const [[rows, nodeMap], setGraph] = useState<[string[][], Dict>]>([[], {}]) useEffect(() => { setGraph(graphUntangled(nodes, inputs, outputs ?? [])) - setTimeout(() => setGraph(graphUntangled(nodes, inputs, outputs ?? [], 5000)), 0) + setTimeout(() => setGraph(graphUntangled(nodes, inputs, outputs ?? [], 3000)), 0) }, [inputs, nodes, outputs]) - /*const rowsWithInOut: (GraphNode|AdditionalNode)[][] = useMemo(() => { - const addedInputs = new Set() - const res: (GraphNode|AdditionalNode)[][] = deepcopy([[], ...rows, []]) - for (let i = 0; i < rows.length; i++) { - const rowOutputs = uniquify(rows[i].flatMap(row => row.outputs)) - for (let rowOutput of rowOutputs) { - outputs?.includes(rowOutput) && res[i+2].push({___type: 'o', value: rowOutput}) - } - const rowInputs = uniquify(rows[i].flatMap(row => row.inputs)) - for (let rowInput of rowInputs) { - if (addedInputs.has(rowInput)) - !res[i].some(node => isAdditionalNode(node) && node.value === rowInput) && res[i].push({___type: 'h', value: rowInput}) - else if (inputs.includes(rowInput)) - res[i].push({___type: 'i', value: rowInput}) - addedInputs.add(rowInput) - } - } - return res - }, [rows, inputs, outputs])*/ - useEffect(() => { if (!planeRef.current) return const plane = planeRef.current @@ -61,22 +41,22 @@ export const ProducingGraph = ,>({nodes, inputs, outputs svg.setAttributeNS(null, 'viewBox', `0 0 ${width} ${height}`) svg.replaceChildren() + let paths: string[] = [] plane.querySelectorAll('[data-outputs]').forEach(startNode => { if (!(startNode instanceof HTMLElement)) return (startNode.dataset.outputs?.split(' ') ?? []).forEach(output => { const endNode = plane.querySelector(`[data-name="${output}"]`) if (!(endNode instanceof HTMLElement)) return - const path = document.createElementNS('http://www.w3.org/2000/svg',"path") - path.setAttributeNS(null, 'd', createPath(plane.getBoundingClientRect(), startNode.getBoundingClientRect(), endNode.getBoundingClientRect())) - svg.appendChild(path) + paths.push(createPath(plane.getBoundingClientRect(), startNode.getBoundingClientRect(), endNode.getBoundingClientRect())) }) }) - plane.querySelectorAll('[data-hidden][data-outputs]').forEach(elem => { + plane.querySelectorAll('[data-hidden="true"][data-outputs]').forEach(elem => { if (!(elem instanceof HTMLElement)) return - const path = document.createElementNS('http://www.w3.org/2000/svg',"path") - path.setAttributeNS(null, 'd', drawLine(plane.getBoundingClientRect(), elem.getBoundingClientRect())) - svg.appendChild(path) + paths.push(drawLine(plane.getBoundingClientRect(), elem.getBoundingClientRect())) }) + const path = document.createElementNS('http://www.w3.org/2000/svg',"path") + path.setAttributeNS(null, 'd', paths.join(' ')) + svg.appendChild(path) }) return
@@ -87,14 +67,17 @@ export const ProducingGraph = ,>({nodes, inputs, outputs const node = nodeMap[uid] return ( !isAdditionalNode(node) - ? + key={node.___uid} + data-hidden={node.___uidOutputs.length > 0}> + + : node.___type === 'h' ? ,>({nodes, inputs, outputs data-hidden={true}> : node.___type === 'i' ? ,>({nodes, inputs, outputs : >(rowsWithInOut: string[][], nod let bestRows = deepcopy(rowsWithInOut) let limit = Date.now() + timeLimit let iterSinceImprovements = 0 + let rng = seedrandom.alea("We are SEEED, ya!") while (true) { if (Date.now() > limit) break if (iterSinceImprovements > 100) break @@ -223,7 +225,7 @@ export function findBest>(rowsWithInOut: string[][], nod } else { iterSinceImprovements++ } - rowsOptimized.forEach(shuffleInplace) + rowsOptimized.forEach((row, ) => shuffleInplace(row, rng)) } console.log(bestScore) return bestRows @@ -244,9 +246,5 @@ export function graphUntangled>(nodes: GraphNode[], i //console.table(rowsWithInOut) //console.table(nodesLinked) const bestRows = findBest(rowsWithInOut, nodesWithInOut, timeLimit) - const orderRow = bestRows.find(row => row.length > 1) - if ((orderRow?.[0]?.localeCompare(orderRow[orderRow.length-1]) ?? 0) > 0) { - bestRows.forEach(row => row.reverse()) - } return [bestRows, nodesLinked] } diff --git a/src/utils.ts b/src/utils.ts index 7b81d68..3b286fe 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,5 @@ import {Dict} from "./types"; +import {PRNG} from "seedrandom"; export function isNonNullable(any: T): any is NonNullable { return any !== undefined && any !== null @@ -26,9 +27,9 @@ export function uniquify(array: T[]): T[] { return Array.from(new Set(array)) } -export function shuffleInplace(array: T[]): T[] { +export function shuffleInplace(array: T[], rng: PRNG): T[] { for (let i = array.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); + const j = Math.floor(rng.quick() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array