diff --git a/src/executor.rs b/src/executor.rs index 6c88403..6cbb152 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -6,6 +6,8 @@ use std::{ use crate::{Algorithm, Maze, Pos}; +use self::builder::{new_builder, BuildableMazeState, ExecutorBuilder, Unprovided}; + /// A guess to pass to the current [`Executor`] at the end of every `progress` call. pub struct Guess(Vec); @@ -79,11 +81,14 @@ impl<'m> Context<'m> { } } +mod builder; + /// A structure holding a [`Maze`] and iteratively solving it with a provided [`Algorithm`]. pub struct Executor where Algo: Algorithm, { + delay: Duration, maze: Maze, algorithm: Algo, } @@ -93,13 +98,32 @@ where A: Algorithm, { /// Constructor. - pub fn new(maze: Maze, algorithm: A) -> Self { - Self { maze, algorithm } + fn new(maze: Maze, algorithm: A, delay: Duration) -> Self { + Self { + maze, + algorithm, + delay, + } + } + + pub fn build<'f, F, MS>(algorithm: A, builder: F) -> Self + where + MS: BuildableMazeState, + F: Fn(ExecutorBuilder) -> ExecutorBuilder, + { + let operation = builder; + let mut builder = (operation)(new_builder()); + let (maze, delay) = builder.build(); + Self::new(maze, algorithm, delay) } /// Submit the maze to the [`Algorithm`] and iteratively progress through the maze driven by said algorithm. pub fn run(&mut self) { - let Self { maze, algorithm } = self; + let Self { + maze, + algorithm, + delay, + } = self; let mut insight = Insight::from_position(maze.start(), &maze); let mut tick = 0; let mut tried = HashSet::new(); @@ -116,7 +140,7 @@ where // draw Self::draw(maze, &tried, tick, &guess); - thread::sleep(Duration::from_millis(100)); + thread::sleep(*delay); tick += 1; // check for next iteration diff --git a/src/executor/builder.rs b/src/executor/builder.rs new file mode 100644 index 0000000..a0d5d74 --- /dev/null +++ b/src/executor/builder.rs @@ -0,0 +1,57 @@ +use std::time::Duration; + +use crate::{labyrinth::generator::MazeGenerator, Maze}; + +pub trait MazeState {} +pub trait BuildableMazeState: MazeState { + fn get(self) -> Maze; +} + +pub struct Unprovided; + +impl MazeState for Unprovided {} + +struct Provided { + maze: Maze, +} + +impl MazeState for Provided {} +impl BuildableMazeState for Provided { + fn get(self) -> Maze { + self.maze + } +} + +struct Generated { + generator: Box, +} + +impl MazeState for Generated {} +impl BuildableMazeState for Generated { + fn get(mut self) -> Maze { + self.generator.generate() + } +} + +pub struct ExecutorBuilder +where + MS: MazeState, +{ + maze_state: MS, + delay: Duration, +} + +pub fn new_builder() -> ExecutorBuilder { + ExecutorBuilder { + maze_state: Unprovided, + delay: Duration::from_millis(100), + } +} + +impl ExecutorBuilder { + pub fn build(self) -> (Maze, Duration) { + let maze = self.maze_state.get(); + let delay = self.delay; + (maze, delay) + } +} diff --git a/src/implementations.rs b/src/implementations.rs index 1f5d035..54fbc40 100644 --- a/src/implementations.rs +++ b/src/implementations.rs @@ -15,8 +15,8 @@ fn depth_first() { use crate::{generate, Executor}; let algorithm = DepthFirst::new(); let maze = generate(20, 20); - let mut executor = Executor::new(maze, algorithm); - executor.run(); + // let mut executor = Executor::new(maze, algorithm); + // executor.run(); } #[test] @@ -24,6 +24,6 @@ fn breath_first() { use crate::{generate, Executor}; let algorithm = BreathFirst::new(); let maze = generate(20, 20); - let mut executor = Executor::new(maze, algorithm); - executor.run(); + // let mut executor = Executor::new(maze, algorithm); + // executor.run(); } diff --git a/src/labyrinth/generator.rs b/src/labyrinth/generator.rs index f4bdfb5..81e76be 100644 --- a/src/labyrinth/generator.rs +++ b/src/labyrinth/generator.rs @@ -44,3 +44,7 @@ fn generation() { let text = maze.display(None); println!("{text}"); } + +pub trait MazeGenerator { + fn generate(&mut self) -> Maze; +}