diff options
| author | a14m <[email protected]> | 2021-04-09 21:38:12 +0200 |
|---|---|---|
| committer | a14m <[email protected]> | 2021-04-09 21:50:18 +0200 |
| commit | 3863d6ca62c75cf08a3dffd509aa9dbea96b894f (patch) | |
| tree | 92309076cb4ec7f88d81e7b2722a0a220f5065e2 /CLI/rust | |
| parent | 4a831d3bf6d9c3541ef34b75104a926999457005 (diff) | |
Add seed generator/populate w/tests
Diffstat (limited to 'CLI/rust')
| -rw-r--r-- | CLI/rust/Cargo.lock | 27 | ||||
| -rw-r--r-- | CLI/rust/Cargo.toml | 3 | ||||
| -rw-r--r-- | CLI/rust/src/game_of_life/generators/seed.rs | 114 |
3 files changed, 140 insertions, 4 deletions
diff --git a/CLI/rust/Cargo.lock b/CLI/rust/Cargo.lock index 841b96e..2ef9298 100644 --- a/CLI/rust/Cargo.lock +++ b/CLI/rust/Cargo.lock @@ -177,6 +177,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41" [[package]] +name = "libm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" + +[[package]] name = "libz-sys" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -227,6 +233,16 @@ dependencies = [ ] [[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] name = "openssl-probe" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -337,6 +353,16 @@ dependencies = [ ] [[package]] +name = "rand_distr" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9e8f32ad24fb80d07d2323a9a2ce8b30d68a62b8cb4df88119ff49a698f038" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] name = "rand_hc" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -418,6 +444,7 @@ dependencies = [ "curl", "mocktopus", "rand", + "rand_distr", "regex", "terminal_size", ] diff --git a/CLI/rust/Cargo.toml b/CLI/rust/Cargo.toml index 41aff9e..90153e5 100644 --- a/CLI/rust/Cargo.toml +++ b/CLI/rust/Cargo.toml @@ -15,10 +15,11 @@ path = "src/main.rs" [dependencies] clap = { version = "3.0.0-beta.2", features = ["wrap_help"] } +ctrlc = "3.1.8" curl = "0.4.35" rand = "0.8.3" +rand_distr = "0.4.0" regex = "1.4.5" -ctrlc = "3.1.8" terminal_size = "0.1.16" [dev-dependencies] diff --git a/CLI/rust/src/game_of_life/generators/seed.rs b/CLI/rust/src/game_of_life/generators/seed.rs index 41c8f5d..e3e3f12 100644 --- a/CLI/rust/src/game_of_life/generators/seed.rs +++ b/CLI/rust/src/game_of_life/generators/seed.rs @@ -1,6 +1,9 @@ use crate::game_of_life::opts::Opts; -use crate::game_of_life::simulation::universe::Universe; +use crate::game_of_life::simulation::{plane::Plane, universe::Universe}; use clap::Error; +use rand::rngs::StdRng; +use rand::{Rng, SeedableRng}; +use rand_distr::{Distribution, Uniform}; #[cfg(test)] use mocktopus::macros::mockable; @@ -10,6 +13,111 @@ use mocktopus::macros::mockable; /// The generation of the seed should be stable across different machines /// using the same language package, version, width and height. #[cfg_attr(test, mockable)] -pub(crate) fn new(_opts: Opts) -> Result<Universe, Error> { - unimplemented!() +pub(crate) fn new(opts: Opts) -> Result<Universe, Error> { + let range = generator(opts.seed); + Ok(populate(opts, range)) +} + +/// Create a StdRng using Uniform distribution for generating same data from +/// the same seed +fn generator(seed: usize) -> StdRng { + let mut range = StdRng::seed_from_u64(seed as u64); + Uniform::new_inclusive(0, 1).sample(&mut range); + range +} + +#[cfg(test)] +mod generator { + use super::*; + + #[test] + fn seed_1337() { + let mut rng = generator(1337); + assert_eq!(rng.gen::<bool>(), true); + assert_eq!(rng.gen::<bool>(), false); + assert_eq!(rng.gen::<bool>(), true); + assert_eq!(rng.gen::<bool>(), true); + assert_eq!(rng.gen::<bool>(), false); + } + + #[test] + fn seed_42() { + let mut rng = generator(42); + assert_eq!(rng.gen::<bool>(), true); + assert_eq!(rng.gen::<bool>(), false); + assert_eq!(rng.gen::<bool>(), true); + assert_eq!(rng.gen::<bool>(), true); + assert_eq!(rng.gen::<bool>(), true); + } +} + +/// Return a universe struct with populated data from the seedable range +fn populate(opts: Opts, mut range: StdRng) -> Universe { + let (width, height) = (opts.width as usize, opts.height as usize); + let mut current = Plane(vec![Plane(vec![false; width]); height]); + for i in 0..height { + for j in 0..width { + current[i as isize][j as isize] = range.gen() + } + } + Universe { + opts, + current, + future: Plane(vec![Plane(vec![false; width]); height]), + } +} + +#[cfg(test)] +mod populate { + use super::*; + + fn opts(seed: usize) -> Opts { + Opts { + seed, + input: None, + width: 5, + height: 3, + live_cell: 'L', + dead_cell: 'D', + delay: 13, + } + } + + #[test] + fn seed_1337() { + let rng = generator(1337); + let opts = opts(1337); + let universe = populate(opts.clone(), rng); + assert_eq!( + universe, + Universe { + opts, + future: Plane(vec![Plane(vec![false; 5]); 3]), + current: Plane(vec![ + Plane(vec![true, false, true, true, false]), + Plane(vec![true, false, true, false, true]), + Plane(vec![false, false, true, true, true]), + ]), + } + ) + } + + #[test] + fn seed_42() { + let rng = generator(42); + let opts = opts(42); + let universe = populate(opts.clone(), rng); + assert_eq!( + universe, + Universe { + opts, + future: Plane(vec![Plane(vec![false; 5]); 3]), + current: Plane(vec![ + Plane(vec![true, false, true, true, true]), + Plane(vec![true, false, true, false, true]), + Plane(vec![false, false, true, false, true]), + ]), + } + ) + } } |
