Visiting cells
Simple enumeration
Section titled “Simple enumeration”By.cells iterates over all cell positions. It runs left-to-right, top-to-bottom.
import { Grids } from '@ixfx/geometry/bundle';const grid = { rows: 5, cols: 5 };for (const cell of Grids.By.cells(grid)) { // { x, y }}
By default it starts at { x: 0, y: 0 }
, but this can be overridden, and you can also ask it to wrap from end to start to ensure all cells are visited.
// Start at 2,2 and wrap aroundfor (const cell of Grids.By.cells(grid, { x: 2, y: 2 }, true)) { // { x, y }}
You can also iterate by column or row , where you get the whole column/row as an array, rather than getting individual cell positions.
for (const col of Grid.As.columns(grid)) { // col is an array of cell positions}
Creating a visitor
Section titled “Creating a visitor”Visit.create lets you visit cells from a position using one of several in-built logics.
Logic | Description |
---|---|
row | left-to-right, top-to-bottom |
column | top-to-bottom, left-to-right |
neighbours | neighbours surrounding cell |
breadth | breadth-first |
depth | depth-first |
random | any random cell in grid |
random-contiguous | any random cell neighbouring an already visited cell |
create
returns a ‘factory’ function capturing the traversal logic. This can then be used with your grid of choice.
import { Grids } from '@ixfx/geometry/bundle';// Create a visitorconst visitor = Grids.Visit.create(`random-contiguous`);
The function in turn gives a generator for iterating over cell positions:
const grid = { rows: 5, cols: 5 };for (const cell of visitor(grid)) { // { x, y }}
It may seem odd that the function Grid.Visit.create
returns a function that returns a function! The reason for this is that we can encapsulate the logic of traversal separately from the state of traversal. Ie., in the above example, we could later call visitor(someOtherGrid)
, reusing the logic with some other grid. It also allows us to combine it with the ‘stepper’, described later.
Options
Section titled “Options”create
takes options for controlling behaviour when the bounds of the grid are reached, amongst others.
In summary, the options are:
boundsWrap: GridBoundsLogic;reversed: boolean;start: GridCell;visited: ISetMutable<GridCell>;
Example usage:
Grids.Visit.create(`row`, { boundsWrap: `stop` reversed: true, start: { x: 2, y: 10 }})
boundsWrap
is Type Grids.GridBoundsLogic . undefined is the default in most operations.
Logic | Description |
---|---|
unbounded | Cell positions allowed to go past grid row/cols |
undefined | Yields undefined when attempting to read outside of limits |
stop | Yield the nearest legal position |
wrap | Wrap around, eg go from end to start of grid |
reversed
runs visitor in reverse, where possible. This doesn’t do anything for the random visitors.
start
specifies the starting cell. By default, { x:0, y:0 }
.
visited
is sometimes useful if you want to monitor which cells have been visited. If you pass in a set, the function will use this internally. The set gets created internally otherwise, but you don’t get access to it.
Stepper
Section titled “Stepper”Visit.stepper runs the visitor for a certain number of steps, returning the final position. The stepper remembers its position, so it becomes a way to asynchronously step through a grid in a way which is not as easy with the generator.
For example, this allows you to get the position three cells away row-wise.
// Row-wise visitorconst visitor = Grids.Visit.create(`row`);
// Create a stepper, starting at a particular positionconst stepper = Grids.Visit.stepper(grid, visitor, { x: 10, y: 2 });
stepper(3); // Get {x,y} position three steps away from start positionstepper(2); // Take another two steps
stepper(4, true); // Take four steps, but reset to start position first