summaryrefslogtreecommitdiffstats
path: root/CLI/rust
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
parent4a831d3bf6d9c3541ef34b75104a926999457005 (diff)
Add seed generator/populate w/tests
Diffstat (limited to 'CLI/rust')
-rw-r--r--CLI/rust/Cargo.lock27
-rw-r--r--CLI/rust/Cargo.toml3
-rw-r--r--CLI/rust/src/game_of_life/generators/seed.rs114
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]),
+ ]),
+ }
+ )
+ }
}