mazer/behaviors/
maze.rs

1use crate::{Grid, Error};
2use crate::cell::Coordinates;
3
4use std::collections::HashSet;
5
6pub trait MazeGeneration {
7    /// Carve a maze on the provided grid.
8    fn generate(&self, grid: &mut Grid) -> Result<(), Error>;
9
10    /// Finalize the maze (set distances, mark solution, etc.).
11    fn finalize(&self, grid: &mut Grid) -> Result<(), Error> {
12        let start = grid.start_coords;
13        let goal = grid.goal_coords;
14    
15        let all_distances = grid.distances(start);
16        for (coords, distance) in all_distances {
17            if let Ok(cell) = grid.get_mut(coords) {
18                cell.distance = distance as i32;
19            }
20        }
21    
22        if let Ok(path) = grid.get_path_to(start.x, start.y, goal.x, goal.y) {
23            for coords in path.keys() {
24                if let Ok(cell) = grid.get_mut(*coords) {
25                    cell.on_solution_path = true;
26                }
27            }
28        }
29   
30        for cell_option in grid.cells.iter_mut() {
31            if let Some(cell) = cell_option {
32                cell.set_open_walls();
33            }
34        }
35    
36        let active_count = grid.cells.iter().filter(|cell| cell.as_ref().map_or(false, |c| c.is_visited)).count();
37        if active_count > 1 {
38            Err(Error::MultipleActiveCells { count: active_count })
39        } else if active_count == 0 {
40            Err(Error::NoActiveCells)
41        } else {
42            Ok(())
43        }
44    }
45
46    // Capture a step with minimal overhead
47    fn capture_step(&self, grid: &mut Grid, changed_cells: &HashSet<Coordinates>) {
48        if grid.capture_steps {
49            // Update open_walls only for changed cells
50            for coord in changed_cells {
51                if let Ok(cell) = grid.get_mut(*coord) {
52                    cell.set_open_walls();
53                }
54            }
55            // Clone the grid minimally for storage
56            let mut grid_clone = grid.clone();
57            grid_clone.capture_steps = false;
58            grid_clone.generation_steps = None; // Prevent recursive cloning
59            grid.generation_steps.as_mut().unwrap().push(grid_clone);
60        }
61    }
62
63    fn build<'a>(&self, grid: &'a mut Grid) -> Result<&'a Grid, Error> {
64        self.generate(grid)?;
65        self.finalize(grid)?;
66        Ok(grid)
67    }
68
69}