enclosedTiles

Find an area of tiles enclosed by 'walls'.

enclosedTiles
(
alias isWall
T
)
if (
is(typeof(isWall(grid.tileAt(RowCol(0, 0)))) : bool)
)

Parameters

isWall

predicate which returns true if a tile should be considered a 'wall'

grid T

grid of tiles to find enclosed area in

origin RowCol

tile that may be part of an enclosed region

diags Diagonals

if yes, an area is not considered enclosed if there is a diagonal opening.

Return Value

Type: auto

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

Examples

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);

Meta