diff --git a/Cargo.lock b/Cargo.lock index a58f65d..e557a16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,23 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - [[package]] name = "bitflags" version = "1.3.2" @@ -31,45 +14,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "clap" -version = "3.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" -dependencies = [ - "atty", - "bitflags", - "clap_derive", - "clap_lex", - "indexmap", - "lazy_static", - "strsim", - "termcolor", - "textwrap", -] - -[[package]] -name = "clap_derive" -version = "3.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" -dependencies = [ - "os_str_bytes", -] - [[package]] name = "getrandom" version = "0.2.6" @@ -81,69 +25,14 @@ dependencies = [ "wasi", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "indexmap" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "labirust" -version = "0.3.0" +version = "0.1.1" dependencies = [ "rand", "termion", ] -[[package]] -name = "labirust" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be89e6ef8c189ed1fa5acb4475a3b43c2aa835c0788fb38b11df3ddb58359f8c" -dependencies = [ - "rand", - "termion", -] - -[[package]] -name = "labirust-cli" -version = "0.1.0" -dependencies = [ - "clap", - "labirust 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.126" @@ -156,60 +45,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" -[[package]] -name = "os_str_bytes" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" - [[package]] name = "ppv-lite86" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - [[package]] name = "rand" version = "0.8.5" @@ -258,32 +99,6 @@ dependencies = [ "redox_syscall", ] -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - [[package]] name = "termion" version = "1.5.6" @@ -296,57 +111,8 @@ dependencies = [ "redox_termios", ] -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - -[[package]] -name = "unicode-ident" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index 509c747..8d62dbe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,12 @@ -[workspace] -members = ["labirust", "labirust-cli"] +[package] +name = "labirust" +version = "0.1.1" +edition = "2021" +license = "MIT" +authors = ["JOLIMAITRE Matthieu "] +description = "Naive rust crate for implementing and testing maze solving Algorithms." +repository = "https://github.com/MajorBarnulf/labirust/" + +[dependencies] +rand = "0.8" +termion = "1.5" diff --git a/labirust/README.md b/README.md similarity index 63% rename from labirust/README.md rename to README.md index 80899ec..c837557 100644 --- a/labirust/README.md +++ b/README.md @@ -14,19 +14,14 @@ Hi, I am a junior rust dev (yes, how original, I know) and this is one of the sm ## Usage -If you want to see what the library is capable of, you can try the CLI, either by clonning this repo and building it with cargo or by installing it through the crates.io depot. +If you want to see what the library is capable of, you can clone this repo and run the tests to see mazes solving themselves on the terminal. + +for you to see anything during the execution of tests, don't forget to add these arguments: ```sh -# installation -cargo install labirust-cli +-- --nocapture -# usage -labirust-cli --help +# example: +cargo test -- implementations::breath_first --nocapture ``` - If you want to implement more resolution algorithm yourself and for some reason you think this is the right crate to provide frameworks, you can explore the crate documentation and add this crate to your project dependencies. -```toml -# in Cargo.toml -[dependencies] -labirust = "0.3" -``` diff --git a/labirust-cli/Cargo.toml b/labirust-cli/Cargo.toml deleted file mode 100644 index 4951c28..0000000 --- a/labirust-cli/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "labirust-cli" -version = "0.1.0" -edition = "2021" -license = "MIT" -authors = ["JOLIMAITRE Matthieu "] -description = "A cli to run labirust algorithms." -repository = "https://github.com/MajorBarnulf/labirust/" - -[dependencies] -labirust = "0.3" -clap = { version = "3.1", features = ["derive"] } diff --git a/labirust-cli/README.md b/labirust-cli/README.md deleted file mode 100644 index c33c727..0000000 --- a/labirust-cli/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# labirust-cli - -## Description - -A cli to run labirust algorithms. - -## Installation - -```sh -# through cargo -cargo install labirust-cli -``` \ No newline at end of file diff --git a/labirust-cli/src/main.rs b/labirust-cli/src/main.rs deleted file mode 100644 index 534713d..0000000 --- a/labirust-cli/src/main.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::str::FromStr; - -use clap::Parser; -use labirust::{implementations::*, Algorithm, Executor, SimpleGenerator}; - -enum Algorithms { - DepthFirst, - BreathFirst, -} - -impl FromStr for Algorithms { - type Err = String; - - fn from_str(s: &str) -> Result { - match s { - "depth-first" => Ok(Self::DepthFirst), - "breath-first" => Ok(Self::BreathFirst), - _ => Err("No right pattern".into()), - } - } -} - -#[derive(Parser)] -struct Parameters { - /// Algorithm to use in the simulation. - /// One of: "depth-first", "breath-first" - algorithm: Algorithms, - - /// Width of the maze to solve. - #[clap(short, default_value_t = 40)] - width: usize, - - /// Height of the maze to solve. - #[clap(short, default_value_t = 20)] - height: usize, - - /// Delay between two simulation ticks. - #[clap(short, default_value_t = 100)] - delay: usize, -} - -fn main() { - let params = Parameters::parse(); - - let algorithm: Box = match params.algorithm { - Algorithms::DepthFirst => Box::new(DepthFirst::new()), - Algorithms::BreathFirst => Box::new(BreathFirst::new()), - }; - - let mut executor = Executor::build_dyn(algorithm, |b| { - b.generated(Box::new(SimpleGenerator::new( - params.width as isize, - params.height as isize, - ))) - }); - - executor.run(); -} diff --git a/labirust/Cargo.toml b/labirust/Cargo.toml deleted file mode 100644 index 44a4360..0000000 --- a/labirust/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "labirust" -version = "0.3.0" -edition = "2021" -license = "MIT" -authors = ["JOLIMAITRE Matthieu "] -description = "Naive rust crate for implementing and testing maze solving Algorithms." -repository = "https://github.com/MajorBarnulf/labirust/" - -[dependencies] -rand = "0.8" -termion = "1.5" diff --git a/labirust/src/executor/builder.rs b/labirust/src/executor/builder.rs deleted file mode 100644 index b63606b..0000000 --- a/labirust/src/executor/builder.rs +++ /dev/null @@ -1,179 +0,0 @@ -use std::time::Duration; - -use crate::{labyrinth::generator::MazeGenerator, Maze}; - -use self::maze_state::{BuildableMazeState, Generated, MazeState, Provided, Unprovided}; - -pub mod maze_state { - - use crate::{labyrinth::generator::MazeGenerator, Maze}; - - /// Describe the state of the [`Maze`] parameter in the builder of an [`crate::Executor`]. Not ment to be implemented. - pub trait MazeState {} - pub trait BuildableMazeState: MazeState { - fn get(&self) -> Maze; - } - - pub struct Unprovided; - - impl MazeState for Unprovided {} - - pub struct Provided { - maze: Maze, - } - - impl Provided { - pub fn new(maze: Maze) -> Self { - Self { maze } - } - } - - impl MazeState for Provided {} - impl BuildableMazeState for Provided { - fn get(&self) -> Maze { - self.maze.clone() - } - } - - pub struct Generated { - generator: Box, - } - - impl Generated { - pub fn new(generator: G) -> Self - where - G: MazeGenerator + 'static, - { - let generator = Box::new(generator); - Self { generator } - } - - pub fn new_dyn(generator: Box) -> Self { - Self { generator } - } - } - - impl MazeState for Generated {} - impl BuildableMazeState for Generated { - fn get(&self) -> Maze { - self.generator.generate() - } - } -} - -/// Builder for an [`crate::Executor`], needs at least a [`Maze`]. -pub struct ExecutorBuilder -where - MS: MazeState, -{ - maze_state: MS, - delay: Duration, -} - -pub(crate) fn new_builder() -> ExecutorBuilder { - ExecutorBuilder { - maze_state: Unprovided, - delay: Duration::from_millis(100), - } -} - -impl ExecutorBuilder { - /// Provide a specific [`Maze`] for the execution. - pub fn maze(self, maze: Maze) -> ExecutorBuilder { - let Self { - delay, - maze_state: _, - } = self; - ExecutorBuilder { - delay, - maze_state: Provided::new(maze), - } - } - - /// Provide a generator to generate a [`Maze`] for the execution. - pub fn generated(self, generator: G) -> ExecutorBuilder - where - G: MazeGenerator + 'static, - { - let Self { - delay, - maze_state: _, - } = self; - ExecutorBuilder { - delay, - maze_state: Generated::new(generator), - } - } - - /// Sets the delay between terminal redraws, default is 100ms. - pub fn delay_ms(self, delay: u64) -> Self { - let delay = Duration::from_millis(delay); - let Self { - maze_state, - delay: _, - } = self; - Self { maze_state, delay } - } -} - -impl ExecutorBuilder { - pub(crate) fn build(self) -> (Maze, Duration) { - let maze = self.maze_state.get(); - let delay = self.delay; - (maze, delay) - } -} - -pub enum DynMazeState { - None, - Provided(Provided), - Generated(Generated), -} - -impl DynMazeState { - pub fn get(self) -> Option { - match self { - DynMazeState::None => None, - DynMazeState::Provided(provided) => Some(provided.get()), - DynMazeState::Generated(generated) => Some(generated.get()), - } - } -} - -pub struct DynExecutorBuilder { - maze: DynMazeState, - delay: Duration, -} - -impl DynExecutorBuilder { - pub(crate) fn new() -> Self { - Self { - maze: DynMazeState::None, - delay: Duration::from_millis(100), - } - } - - pub fn maze(self, maze: Maze) -> Self { - let maze = DynMazeState::Provided(Provided::new(maze)); - let Self { maze: _, delay } = self; - Self { maze, delay } - } - - pub fn generated(self, generator: Box) -> Self { - let maze = DynMazeState::Generated(Generated::new_dyn(generator)); - let Self { maze: _, delay } = self; - Self { delay, maze } - } - - pub fn delay_ms(self, delay: u64) -> Self { - let delay = Duration::from_millis(delay); - let Self { maze, delay: _ } = self; - Self { maze, delay } - } - - pub(crate) fn build(self) -> (Maze, Duration) { - let maze = self.maze.get().expect("no buildable maze provided"); - let delay = self.delay; - (maze, delay) - } -} diff --git a/labirust/src/labyrinth/generator.rs b/labirust/src/labyrinth/generator.rs deleted file mode 100644 index e540666..0000000 --- a/labirust/src/labyrinth/generator.rs +++ /dev/null @@ -1,66 +0,0 @@ -//! ## Generator -//! -//! This module contains raw functions generating mazes. - -use std::collections::HashSet; - -use rand::{prelude::SliceRandom, thread_rng}; - -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. -pub struct SimpleGenerator { - width: isize, - height: isize, -} - -impl SimpleGenerator { - pub fn new(width: isize, height: isize) -> Self { - Self { height, width } - } -} - -impl MazeGenerator for SimpleGenerator { - fn generate(&self) -> Maze { - let Self { width, height } = *self; - let mut result = Maze::new( - width, - height, - Pos::zero(), - (width - 1, height - 1).into(), - Vec::new(), - ); - - fn recursive(current: Pos, result: &mut Maze, visited: &mut HashSet) { - 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] -fn generation() { - let generator = SimpleGenerator::new(10, 10); - let maze = generator.generate(); - let text = maze.display(None); - println!("{text}"); -} diff --git a/labirust/src/algorithm.rs b/src/algorithm.rs similarity index 100% rename from labirust/src/algorithm.rs rename to src/algorithm.rs diff --git a/labirust/src/executor.rs b/src/executor.rs similarity index 74% rename from labirust/src/executor.rs rename to src/executor.rs index b9e3320..6cbb152 100644 --- a/labirust/src/executor.rs +++ b/src/executor.rs @@ -1,8 +1,3 @@ -//! ## Executor -//! -//! This module contains the definition of an [`Executor`], used to run an [`Algorithm`] and have a graphical output in the terminal. -//! This type is supposed to be created using the builder pattern (c.f. [`Executor`]`::build`). - use std::{ collections::{HashMap, HashSet}, thread, @@ -11,10 +6,7 @@ use std::{ use crate::{Algorithm, Maze, Pos}; -use self::builder::{ - maze_state::{BuildableMazeState, Unprovided}, - new_builder, DynExecutorBuilder, ExecutorBuilder, -}; +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); @@ -92,15 +84,21 @@ impl<'m> Context<'m> { mod builder; /// A structure holding a [`Maze`] and iteratively solving it with a provided [`Algorithm`]. -pub struct Executor { +pub struct Executor +where + Algo: Algorithm, +{ delay: Duration, maze: Maze, - algorithm: Box, + algorithm: Algo, } -impl Executor { +impl Executor +where + A: Algorithm, +{ /// Constructor. - fn new(maze: Maze, algorithm: Box, delay: Duration) -> Self { + fn new(maze: Maze, algorithm: A, delay: Duration) -> Self { Self { maze, algorithm, @@ -108,25 +106,13 @@ impl Executor { } } - pub fn build<'f, A, F, MS>(algorithm: A, builder: F) -> Self + pub fn build<'f, F, MS>(algorithm: A, builder: F) -> Self where - A: Algorithm + 'static, MS: BuildableMazeState, F: Fn(ExecutorBuilder) -> ExecutorBuilder, { let operation = builder; - let builder = (operation)(new_builder()); - let (maze, delay) = builder.build(); - let algorithm = Box::new(algorithm); - Self::new(maze, algorithm, delay) - } - - pub fn build_dyn(algorithm: Box, builder: F) -> Self - where - F: Fn(DynExecutorBuilder) -> DynExecutorBuilder, - { - let operation = builder; - let builder = (operation)(DynExecutorBuilder::new()); + let mut builder = (operation)(new_builder()); let (maze, delay) = builder.build(); Self::new(maze, algorithm, delay) } @@ -169,26 +155,25 @@ impl Executor { fn draw(maze: &Maze, tried: &HashSet, tick: usize, path: &Vec) { let mut overlay = HashMap::new(); for position in tried { - overlay.insert(*position, '░'); + overlay.insert(*position, '#'); } - for position in path { - overlay.insert(*position, '█'); - } - overlay.insert(maze.start(), 'S'); - overlay.insert(maze.end(), 'E'); - overlay.insert(*path.last().unwrap(), 'G'); - let grid = maze.display(Some(overlay)); - let text = format!("tick {tick}:\n{grid}\n"); + for position in path { + overlay.insert(*position, 'P'); + } + + overlay.insert(*path.last().unwrap(), 'x'); + + let text = maze.display(Some(overlay)); // DIRTY! // print the frame on top of the previous one if tick > 0 { - let count = text.lines().count(); + let count = text.lines().count() + 1; let up = termion::cursor::Up(count as u16); print!("{up}") } - print!("{text}"); + print!("tick {tick}:\n{text}\n"); } } 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/labirust/src/implementations.rs b/src/implementations.rs similarity index 57% rename from labirust/src/implementations.rs rename to src/implementations.rs index 1c906a5..54fbc40 100644 --- a/labirust/src/implementations.rs +++ b/src/implementations.rs @@ -12,16 +12,18 @@ pub use depth_first::DepthFirst; #[test] fn depth_first() { - use crate::{Executor, SimpleGenerator}; + use crate::{generate, Executor}; let algorithm = DepthFirst::new(); - let mut executor = Executor::build(algorithm, |b| b.generated(SimpleGenerator::new(40, 20))); - executor.run(); + let maze = generate(20, 20); + // let mut executor = Executor::new(maze, algorithm); + // executor.run(); } #[test] fn breath_first() { - use crate::{Executor, SimpleGenerator}; + use crate::{generate, Executor}; let algorithm = BreathFirst::new(); - let mut executor = Executor::build(algorithm, |b| b.generated(SimpleGenerator::new(40, 20))); - executor.run(); + let maze = generate(20, 20); + // let mut executor = Executor::new(maze, algorithm); + // executor.run(); } diff --git a/labirust/src/implementations/breath_first.rs b/src/implementations/breath_first.rs similarity index 100% rename from labirust/src/implementations/breath_first.rs rename to src/implementations/breath_first.rs diff --git a/labirust/src/implementations/depth_first.rs b/src/implementations/depth_first.rs similarity index 100% rename from labirust/src/implementations/depth_first.rs rename to src/implementations/depth_first.rs diff --git a/labirust/src/labyrinth.rs b/src/labyrinth.rs similarity index 100% rename from labirust/src/labyrinth.rs rename to src/labyrinth.rs diff --git a/src/labyrinth/generator.rs b/src/labyrinth/generator.rs new file mode 100644 index 0000000..81e76be --- /dev/null +++ b/src/labyrinth/generator.rs @@ -0,0 +1,50 @@ +//! ## Generator +//! +//! This module contains raw functions generating mazes. + +use std::collections::HashSet; + +use rand::{prelude::SliceRandom, thread_rng}; + +use crate::{Maze, Pos}; + +/// 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 { + let mut result = Maze::new( + width, + height, + Pos::zero(), + (width - 1, height - 1).into(), + Vec::new(), + ); + + fn recursive(current: Pos, result: &mut Maze, visited: &mut HashSet) { + 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] +fn generation() { + let maze = generate(20, 20); + let text = maze.display(None); + println!("{text}"); +} + +pub trait MazeGenerator { + fn generate(&mut self) -> Maze; +} diff --git a/labirust/src/lib.rs b/src/lib.rs similarity index 86% rename from labirust/src/lib.rs rename to src/lib.rs index 8d0d348..ad82e27 100644 --- a/labirust/src/lib.rs +++ b/src/lib.rs @@ -14,8 +14,5 @@ mod position; pub use algorithm::Algorithm; pub use executor::{Context, Executor, Guess, Insight}; -pub use labyrinth::{ - generator::{MazeGenerator, SimpleGenerator}, - Maze, -}; +pub use labyrinth::{generator::generate, Maze}; pub use position::Pos; diff --git a/labirust/src/position.rs b/src/position.rs similarity index 100% rename from labirust/src/position.rs rename to src/position.rs