///|
pub(all) struct GridMetrics {
open_ratio : Double
room_count : Int
connectivity : Bool
largest_component : Int
dead_end_count : Int
} derive(Show)
///|
fn is_walkable(tile : Tile) -> Bool {
match tile {
Floor | Door | LockedDoor | Key | Start | Goal | Corridor => true
_ => false
}
}
///|
pub fn flood_fill(grid : Grid2D, start_x : Int, start_y : Int) -> Array[Point] {
let visited : Array[Point] = []
let seen = Array::make(grid.width * grid.height, false)
let stack : Array[Point] = [{ x: start_x, y: start_y }]
seen[start_y * grid.width + start_x] = true
while stack.length() > 0 {
let p = stack.pop().unwrap()
visited.push(p)
let neighbors = grid.neighbors4(p.x, p.y)
for n in neighbors {
let idx = n.y * grid.width + n.x
if not(seen[idx]) && is_walkable(grid.get(n.x, n.y)) {
seen[idx] = true
stack.push(n)
}
}
}
visited
}
///|
pub fn compute_metrics(grid : Grid2D, room_count : Int) -> GridMetrics {
let total = grid.width * grid.height
let mut walkable = 0
let mut dead_ends = 0
let mut first_walkable : Point? = None
for y in 0.. 0 {
walkable.to_double() / total.to_double()
} else {
0.0
}
let (connectivity, largest) = match first_walkable {
Some(p) => {
let component = flood_fill(grid, p.x, p.y)
(component.length() == walkable, component.length())
}
None => (true, 0)
}
{
open_ratio,
room_count,
connectivity,
largest_component: largest,
dead_end_count: dead_ends,
}
}