@thi.ng/grid-iterators
Version: 
2D grid and shape iterators w/ multiple orderings
53 lines (52 loc) • 1.13 kB
JavaScript
import { BitField, defBitField } from "@thi.ng/bitfield/bitfield";
function* floodFill(pred, x, y, width, height) {
  x |= 0;
  y |= 0;
  if (!pred(x, y)) return;
  const queue = [[x, y]];
  const visited = defBitField(width * height);
  height--;
  const state = { pred, queue, visited, width, height };
  while (queue.length) {
    [x, y] = queue.pop();
    yield* __partialRow(state, x, y, -1);
    yield* __partialRow(state, x + 1, y, 1);
  }
}
function* __partialRow({
  pred,
  queue,
  visited,
  width,
  height
}, x, y, step) {
  let idx = y * width + x;
  if (visited.at(idx)) return;
  let scanUp = false;
  let scanDown = false;
  while (x >= 0 && x < width && pred(x, y)) {
    visited.setAt(idx);
    yield [x, y];
    if (y > 0) {
      if (pred(x, y - 1) && !scanUp) {
        queue.push([x, y - 1]);
        scanUp = true;
      } else {
        scanUp = false;
      }
    }
    if (y < height) {
      if (pred(x, y + 1) && !scanDown) {
        queue.push([x, y + 1]);
        scanDown = true;
      } else {
        scanDown = false;
      }
    }
    x += step;
    idx += step;
  }
}
export {
  floodFill
};