use std::collections::{HashSet, VecDeque};
use turtle::rand::shuffle;
use crate::grid::Grid;
#[derive(Debug)]
pub struct Maze {
grid: Grid,
start: (usize, usize),
finish: (usize, usize),
}
impl Maze {
pub fn generate() -> Self {
let mut grid = Grid::new();
let mut visited = HashSet::<(usize, usize)>::new();
let mut remaining = VecDeque::<(usize, usize)>::new();
remaining.push_back((0, 0));
while let Some(current) = remaining.pop_front() {
if visited.contains(¤t) {
continue;
}
visited.insert(current);
let adjacents = grid.adjacent_cells(current);
if grid.get(current).is_all_closed() {
let mut visited_adjacents = adjacents.iter().filter(|&p| visited.contains(p)).collect::<Vec<_>>();
shuffle(&mut visited_adjacents);
if let Some(&&adj) = visited_adjacents.first() {
grid.open_between(current, adj);
}
}
let mut unvisited = adjacents.into_iter().filter(|p| !visited.contains(p)).collect::<Vec<_>>();
if !unvisited.is_empty() {
shuffle(&mut unvisited);
let mut unvisited = unvisited.into_iter();
let next = unvisited.next().unwrap();
remaining.push_front(next);
remaining.extend(unvisited);
grid.open_between(current, next);
}
}
let start = (0, 0);
let finish = (grid.col_size() - 1, grid.row_size() - 1);
Self { grid, start, finish }
}
pub fn start(&self) -> (usize, usize) {
self.start
}
pub fn finish(&self) -> (usize, usize) {
self.finish
}
pub fn grid(&self) -> &Grid {
&self.grid
}
}