Function enclosedTiles

Find an area of tiles enclosed by 'walls'.

Prototype

auto enclosedTiles(alias isWall, T)(
  T grid,
  RowCol origin,
  Diagonals diags = Diagonals.no
)
if (is(typeof(isWall(grid.tileAt(RowCol(0, 0)))) : bool));

Parameters

NameDescription
isWall predicate which returns true if a tile should be considered a 'wall'
grid grid of tiles to find enclosed area in
origin tile that may be part of an enclosed region
diags if yes, an area is not considered enclosed if there is a diagonal opening.

Returns

a range of tiles in the enclosure (empty if origin is not part of an enclosed region)

Example

import std.array;
import std.algorithm : equal;

// let the 'X's represent 'walls', and the other letters 'open' areas we'd link to identify
auto tiles = rectGrid([
  // 0    1    2    3    4    5 <-col| row
  [ 'X', 'X', 'X', 'X', 'X', 'X' ], // 0
  [ 'X', 'a', 'a', 'X', 'b', 'X' ], // 1
  [ 'X', 'a', 'a', 'X', 'b', 'X' ], // 2
  [ 'X', 'X', 'X', 'X', 'X', 'X' ], // 3
  [ 'd', 'd', 'd', 'X', 'c', 'X' ], // 4
  [ 'd', 'd', 'd', 'X', 'X', 'c' ], // 5
]);

static bool isWall(char c) { return c == 'X'; }

// starting on a wall should return an empty result
assert(tiles.enclosedTiles!isWall(RowCol(0, 0)).empty);

// all tiles in the [1,1] -> [2,2] area should find the 'a' room
assert(tiles.enclosedTiles!isWall(RowCol(1, 1)).equal(['a', 'a', 'a', 'a']));
assert(tiles.enclosedTiles!isWall(RowCol(1, 2)).equal(['a', 'a', 'a', 'a']));
assert(tiles.enclosedTiles!isWall(RowCol(2, 1)).equal(['a', 'a', 'a', 'a']));
assert(tiles.enclosedTiles!isWall(RowCol(2, 2)).equal(['a', 'a', 'a', 'a']));

// get the two-tile 'b' room at [1,4] -> [2,4]
assert(tiles.enclosedTiles!isWall(RowCol(1, 4)).equal(['b', 'b']));
assert(tiles.enclosedTiles!isWall(RowCol(2, 4)).equal(['b', 'b']));

// get the single tile 'c' room at 4,4
assert(tiles.enclosedTiles!isWall(RowCol(4, 4)).equal(['c']));
// if we require that diagonals be blocked too, 'c' is not an enclosure
assert(tiles.enclosedTiles!isWall(RowCol(4, 4), Diagonals.yes).empty);

// the 'd' region is not an enclosure (touches map edge)
assert(tiles.enclosedTiles!isWall(RowCol(4, 1)).empty);
assert(tiles.enclosedTiles!isWall(RowCol(5, 0)).empty);

Authors

Copyright

License