summaryrefslogtreecommitdiffstats
path: root/CLI/rust/src/game_of_life/generators/seed.rs
diff options
context:
space:
mode:
authora14m <[email protected]>2021-04-09 21:38:12 +0200
committera14m <[email protected]>2021-04-09 21:50:18 +0200
commit3863d6ca62c75cf08a3dffd509aa9dbea96b894f (patch)
tree92309076cb4ec7f88d81e7b2722a0a220f5065e2 /CLI/rust/src/game_of_life/generators/seed.rs
parent4a831d3bf6d9c3541ef34b75104a926999457005 (diff)
Add seed generator/populate w/tests
Diffstat (limited to 'CLI/rust/src/game_of_life/generators/seed.rs')
-rw-r--r--CLI/rust/src/game_of_life/generators/seed.rs114
1 files changed, 111 insertions, 3 deletions
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]),
+ ]),
+ }
+ )
+ }
}