use crate::grid::{Cell, Grid, Point};
use rand::seq::SliceRandom;
pub fn generate_maze(width: usize, height: usize) -> Grid {
assert!(width % 2 != 0 && height % 2 != 0, "Width and height must be odd.");
let mut grid = Grid::new(width, height, Cell::Blocked);
let mut stack: Vec<Point> = Vec::new();
let mut rng = rand::rng();
let start_point = Point::new(1, 1);
grid[start_point] = Cell::Free;
stack.push(start_point);
while let Some(current) = stack.last().copied() {
let mut directions = [(-2, 0), (2, 0), (0, -2), (0, 2)];
directions.shuffle(&mut rng);
let mut moved = false;
for (dx, dy) in directions {
let nx = current.x as isize + dx;
let ny = current.y as isize + dy;
if nx > 0 && nx < width as isize - 1 && ny > 0 && ny < height as isize - 1 {
let next_point = Point::new(nx as usize, ny as usize);
if grid[next_point] == Cell::Blocked {
grid[next_point] = Cell::Free;
let wall_point = Point::new((current.x as isize + dx / 2) as usize, (current.y as isize + dy / 2) as usize);
grid[wall_point] = Cell::Free;
stack.push(next_point);
moved = true;
break;
}
}
}
if !moved {
stack.pop(); }
}
grid[Point::new(0, 1)] = Cell::Free;
grid[Point::new(width - 1, height - 2)] = Cell::Free;
grid
}