///|
let rand : @random.Rand = @random.Rand::new()
///|
struct Grid {
size : Int
cells : FixedArray[FixedArray[Tile?]]
} derive(ToJson, FromJson)
///|
fn empty_cells(size : Int) -> FixedArray[FixedArray[Tile?]] {
FixedArray::makei(size, _ => FixedArray::make(size, None))
}
///|
pub fn Grid::new(size : Int) -> Grid {
{ size, cells: empty_cells(size), }
}
///|
pub fn Grid::copy(grid : Grid) -> Grid {
let cells = FixedArray::makei(grid.size, i => {
FixedArray::makei(grid.size, j => grid.cells[i][j])
})
{ size: grid.size, cells, }
}
///|
pub fn Grid::random_available_cell(self : Grid) -> Position? {
match self.available_cells().collect() {
[] => None
cells => Some(cells[rand.int(limit=cells.length())])
}
}
///|
pub fn Grid::available_cells(self : Grid) -> Iter[Position] {
(0)
.until(self.size)
.flat_map(x => {
(0)
.until(self.size)
.filter_map(y => {
if self.cells[x][y] is None {
Some({ x, y, })
} else {
None
}
})
})
}
///|
pub fn Grid::each_cell(self : Grid) -> Iter[Tile?] {
self.cells.iter().flat_map(row => row.iter())
}
///|
pub fn Grid::cells_available(self : Grid) -> Bool {
self.available_cells().any(_ => true)
}
///|
pub fn Grid::cell_available(self : Grid, pos : Position) -> Bool {
!self.cell_occupied(pos)
}
///|
pub fn Grid::cell_occupied(self : Grid, pos : Position) -> Bool {
self.cell_content(pos) is Some(_)
}
///|
pub fn Grid::cell_content(self : Grid, pos : Position) -> Tile? {
if self.within_bounds(pos) {
self.cells[pos.x][pos.y]
} else {
None
}
}
///|
pub fn Grid::insert_tile(self : Grid, tile : Tile) -> Unit {
self.cells[tile.pos.x][tile.pos.y] = Some(tile)
}
///|
pub fn Grid::remove_tile(self : Grid, pos : Position) -> Unit {
self.cells[pos.x][pos.y] = None
}
///|
pub fn Grid::within_bounds(self : Grid, pos : Position) -> Bool {
pos.x >= 0 && pos.x < self.size && pos.y >= 0 && pos.y < self.size
}