state = {
const [S, E] = backwards
? [terrain.end, terrain.start]
: [terrain.start, terrain.end];
function walk(tree, active) {
let node = d3.least(active, (d) =>
Math.hypot((d % w) - (E % w), ((d / w) | 0) - ((E / w) | 0))
);
const path = [node];
while (tree.has(node)) path.push((node = tree.get(node)));
return path;
}
const tree = new Map();
const active = new Set([S]);
const costs = new Array(V.length).fill(Infinity);
costs[S] = 0;
let t = 0;
const t0 = performance.now();
do {
const node = active.values().next().value;
active.delete(node);
const x = node % w;
const y = (node / w) | 0;
for (const nei of [
x > 0 && node - 1,
x < w - 1 && node + 1,
y > 0 && node - w,
y < h - 1 && node + w
]) {
if (nei === false) continue;
if ((backwards ? -1 : 1) * (V[nei] - V[node]) <= 1) {
const c = costs[node] + 1;
if (c < costs[nei]) {
costs[nei] = c;
active.add(nei);
tree.set(nei, node);
}
}
}
if (++t % steps === 0) {
yield { costs, active, tree, time: t, walk: walk(tree, active) };
}
} while (active.size);
const perf = performance.now() - t0;
yield { costs, active, tree, time: t, walk: walk(tree, [E]), perf };
}