implemented generator and updated examples

This commit is contained in:
JOLIMAITRE Matthieu 2022-05-30 02:03:02 +03:00
parent d0c44cdcbe
commit b21dc88b68
4 changed files with 55 additions and 38 deletions

View file

@ -50,7 +50,7 @@ pub mod maze_state {
impl MazeState for Generated {} impl MazeState for Generated {}
impl BuildableMazeState for Generated { impl BuildableMazeState for Generated {
fn get(mut self) -> Maze { fn get(self) -> Maze {
self.generator.generate() self.generator.generate()
} }
} }

View file

@ -12,18 +12,16 @@ pub use depth_first::DepthFirst;
#[test] #[test]
fn depth_first() { fn depth_first() {
use crate::{generate, Executor}; use crate::{Executor, SimpleGenerator};
let algorithm = DepthFirst::new(); let algorithm = DepthFirst::new();
let maze = generate(20, 20); let mut executor = Executor::build(algorithm, |b| b.generated(SimpleGenerator::new(40, 20)));
// let mut executor = Executor::new(maze, algorithm); executor.run();
// executor.run();
} }
#[test] #[test]
fn breath_first() { fn breath_first() {
use crate::{generate, Executor}; use crate::{Executor, SimpleGenerator};
let algorithm = BreathFirst::new(); let algorithm = BreathFirst::new();
let maze = generate(20, 20); let mut executor = Executor::build(algorithm, |b| b.generated(SimpleGenerator::new(40, 20)));
// let mut executor = Executor::new(maze, algorithm); executor.run();
// executor.run();
} }

View file

@ -8,43 +8,59 @@ use rand::{prelude::SliceRandom, thread_rng};
use crate::{Maze, Pos}; use crate::{Maze, Pos};
/// Trait encapsulating the behavior of a type capable to create mazes.
pub trait MazeGenerator {
fn generate(&self) -> Maze;
}
/// Most common maze generation technique, recursively creating paths to unvisited cells, each time choosing next direction at random. /// Most common maze generation technique, recursively creating paths to unvisited cells, each time choosing next direction at random.
pub fn generate(width: isize, height: isize) -> Maze { pub struct SimpleGenerator {
let mut result = Maze::new( width: isize,
width, height: isize,
height, }
Pos::zero(),
(width - 1, height - 1).into(),
Vec::new(),
);
fn recursive(current: Pos, result: &mut Maze, visited: &mut HashSet<Pos>) { impl SimpleGenerator {
visited.insert(current); pub fn new(width: isize, height: isize) -> Self {
let mut adjascent_positions = result.adjascent(current); Self { height, width }
adjascent_positions.shuffle(&mut thread_rng());
for neighbor in adjascent_positions {
if visited.contains(&neighbor) {
continue;
}
result.create_path(current, neighbor);
recursive(neighbor, result, visited);
}
} }
}
let mut visited = HashSet::new(); impl MazeGenerator for SimpleGenerator {
let current = Pos::zero(); fn generate(&self) -> Maze {
recursive(current, &mut result, &mut visited); let Self { width, height } = *self;
let mut result = Maze::new(
width,
height,
Pos::zero(),
(width - 1, height - 1).into(),
Vec::new(),
);
result fn recursive(current: Pos, result: &mut Maze, visited: &mut HashSet<Pos>) {
visited.insert(current);
let mut adjascent_positions = result.adjascent(current);
adjascent_positions.shuffle(&mut thread_rng());
for neighbor in adjascent_positions {
if visited.contains(&neighbor) {
continue;
}
result.create_path(current, neighbor);
recursive(neighbor, result, visited);
}
}
let mut visited = HashSet::new();
let current = Pos::zero();
recursive(current, &mut result, &mut visited);
result
}
} }
#[test] #[test]
fn generation() { fn generation() {
let maze = generate(20, 20); let generator = SimpleGenerator::new(10, 10);
let maze = generator.generate();
let text = maze.display(None); let text = maze.display(None);
println!("{text}"); println!("{text}");
} }
pub trait MazeGenerator {
fn generate(&mut self) -> Maze;
}

View file

@ -14,5 +14,8 @@ mod position;
pub use algorithm::Algorithm; pub use algorithm::Algorithm;
pub use executor::{Context, Executor, Guess, Insight}; pub use executor::{Context, Executor, Guess, Insight};
pub use labyrinth::{generator::generate, Maze}; pub use labyrinth::{
generator::{MazeGenerator, SimpleGenerator},
Maze,
};
pub use position::Pos; pub use position::Pos;