import type { GameGraph, NodeId } from "./types"; export function axialNeighbors(q: number, r: number): Array<[number, number]> { return [ [q + 1, r], [q + 1, r - 1], [q, r - 1], [q - 1, r], [q - 1, r + 1], [q, r + 1], ]; } export function shortestPathLength( graph: GameGraph, from: NodeId, to: NodeId, ): number { if (!graph.nodes[from] || !graph.nodes[to]) { return Infinity; } if (from === to) { return 0; } const queue: Array<[NodeId, number]> = [[from, 0]]; let head = 0; const visited = new Set([from]); while (head < queue.length) { const [current, distance] = queue[head]; head += 1; const node = graph.nodes[current]; for (const neighbor of node.neighbors) { if (neighbor === to) { return distance + 1; } if (!visited.has(neighbor) && graph.nodes[neighbor]) { visited.add(neighbor); queue.push([neighbor, distance + 1]); } } } return Infinity; } export function isConnected(graph: GameGraph): boolean { const nodeIds = Object.keys(graph.nodes); if (nodeIds.length <= 1) { return true; } const start = nodeIds[0]; const visited = new Set([start]); const queue: NodeId[] = [start]; let head = 0; while (head < queue.length) { const current = queue[head]; head += 1; const node = graph.nodes[current]; for (const neighbor of node.neighbors) { if (!visited.has(neighbor) && graph.nodes[neighbor]) { visited.add(neighbor); queue.push(neighbor); } } } return visited.size === nodeIds.length; }