///|
pub(all) struct Grid2D {
width : Int
height : Int
cells : Array[Tile]
}
///|
pub fn Grid2D::make(width : Int, height : Int, fill : Tile) -> Grid2D {
{ width, height, cells: Array::make(width * height, fill) }
}
///|
pub fn Grid2D::in_bounds(self : Grid2D, x : Int, y : Int) -> Bool {
x >= 0 && x < self.width && y >= 0 && y < self.height
}
///|
pub fn Grid2D::get(self : Grid2D, x : Int, y : Int) -> Tile {
self.cells[y * self.width + x]
}
///|
pub fn Grid2D::set(self : Grid2D, x : Int, y : Int, tile : Tile) -> Unit {
self.cells[y * self.width + x] = tile
}
///|
pub fn Grid2D::fill_rect(
self : Grid2D,
rect : Rect,
tile : Tile
) -> Unit {
for y in rect.y..<(rect.y + rect.h) {
for x in rect.x..<(rect.x + rect.w) {
if self.in_bounds(x, y) {
self.set(x, y, tile)
}
}
}
}
///|
pub fn Grid2D::carve_line(
self : Grid2D,
from : Point,
to : Point,
tile : Tile
) -> Unit {
let mut x = from.x
let mut y = from.y
while x != to.x || y != to.y {
if self.in_bounds(x, y) {
self.set(x, y, tile)
}
if x != to.x {
if x < to.x {
x += 1
} else {
x -= 1
}
} else if y != to.y {
if y < to.y {
y += 1
} else {
y -= 1
}
}
}
if self.in_bounds(to.x, to.y) {
self.set(to.x, to.y, tile)
}
}
///|
pub fn Grid2D::carve_l_corridor(
self : Grid2D,
from : Point,
to : Point,
tile : Tile
) -> Unit {
let mid : Point = { x: to.x, y: from.y }
self.carve_line(from, mid, tile)
self.carve_line(mid, to, tile)
}
///|
pub fn Grid2D::neighbors4(
self : Grid2D,
x : Int,
y : Int
) -> Array[Point] {
let dirs : Array[(Int, Int)] = [(-1, 0), (1, 0), (0, -1), (0, 1)]
let result : Array[Point] = []
for d in dirs {
let nx = x + d.0
let ny = y + d.1
if self.in_bounds(nx, ny) {
result.push({ x: nx, y: ny })
}
}
result
}
///|
pub fn Grid2D::count_neighbors(
self : Grid2D,
x : Int,
y : Int,
tile : Tile
) -> Int {
let mut count = 0
for dx in -1..=1 {
for dy in -1..=1 {
if dx == 0 && dy == 0 {
continue
}
let nx = x + dx
let ny = y + dy
if self.in_bounds(nx, ny) && self.get(nx, ny) == tile {
count += 1
}
}
}
count
}
///|
pub fn Grid2D::to_ascii(self : Grid2D) -> String {
let buf = StringBuilder::new()
for y in 0.. Grid2D {
{ width: self.width, height: self.height, cells: self.cells.copy() }
}