use std::cmp::min;
use std::collections::VecDeque;
use crate::structure::matrix::*;
use crate::structure::types::*;
use crate::structure::wall::*;
pub fn bfs(mat: &mut Matrix, walls: &mut Walls, i: usize, j: usize) {
if i >= mat.rows || j >= mat.cols {
return;
}
let mut queue = VecDeque::<(Location, Option<Location>)>::new();
queue.push_back(((i, j), None));
mat.put(i, j, true);
while !queue.is_empty() {
let (curr_loc, prev_loc) = queue.pop_front().unwrap();
if prev_loc != None {
let left_or_right = curr_loc.1 != prev_loc.unwrap().1;
if left_or_right {
walls.remove_wall(
min(curr_loc.1, prev_loc.unwrap().1),
curr_loc.0,
left_or_right,
);
} else {
walls.remove_wall(
min(curr_loc.0, prev_loc.unwrap().0),
curr_loc.1,
left_or_right,
);
}
}
let locations = mat.get_neighbours(curr_loc.0, curr_loc.1);
for neighbour in locations.iter() {
if !mat.at(neighbour.0, neighbour.1) {
mat.put(neighbour.0, neighbour.1, true);
queue.push_back((*neighbour, Some(curr_loc)));
}
}
}
}
#[cfg(test)]
mod bfs_test {
use super::*;
#[test]
fn visited_all_cells() {
let rows = 5;
let cols = 5;
let mut mat = Matrix::new(rows, cols);
let mut walls = Walls::new(rows - 1, cols - 1);
bfs(&mut mat, &mut walls, 1, 3);
for i in 0..mat.rows {
for j in 0..mat.cols {
assert_eq!(mat.at(i, j), true);
}
}
}
}