use super::Algorithm;
use crate::maze::grid::cell::Cell;
use crate::maze::grid::Grid;
use crate::utils::types::Coords;
use clap::ValueEnum;
use rand::prelude::*;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
pub enum Bias {
NorthWest,
NorthEast,
SouthWest,
SouthEast,
}
pub struct BinaryTree {
bias: Bias,
}
impl BinaryTree {
pub const fn new(bias: Bias) -> BinaryTree {
BinaryTree { bias }
}
fn populate_dirs(&self, coords: Coords, grid: &Grid) -> Vec<Cell> {
let mut dirs = vec![];
let (x, y) = coords;
match self.bias {
Bias::NorthWest => {
if y > 0 {
dirs.push(Cell::NORTH)
}
if x > 0 {
dirs.push(Cell::WEST)
}
}
Bias::NorthEast => {
if y > 0 {
dirs.push(Cell::NORTH)
}
if x + 1 < grid.width() {
dirs.push(Cell::EAST)
}
}
Bias::SouthWest => {
if y + 1 < grid.height() {
dirs.push(Cell::SOUTH)
}
if x > 0 {
dirs.push(Cell::WEST)
}
}
Bias::SouthEast => {
if y + 1 < grid.height() {
dirs.push(Cell::SOUTH)
}
if x + 1 < grid.width() {
dirs.push(Cell::EAST)
}
}
}
dirs
}
}
impl Algorithm for BinaryTree {
fn generate(&mut self, grid: &mut Grid, rng: &mut StdRng) {
for y in 0..grid.height() {
for x in 0..grid.width() {
let dirs = self.populate_dirs((x, y), grid);
if let Some(dir) = dirs.choose(rng) {
grid.carve_passage((x, y), *dir).ok();
}
}
}
}
}