Skip to main content

antbox_state/
genparams.rs

1use antbox_cellauto::{Cell, ConwaysLife, Generation};
2use antbox_geom::Bounds;
3use clap::Args;
4use derive_more::{From, Into};
5use derive_new::new;
6use rand::distr::Distribution;
7use rand::rngs::StdRng;
8use rand::{Rng, SeedableRng as _};
9
10use crate::State;
11
12/// A [Distribution] for generating a [State]
13#[derive(Args, Copy, Clone, Debug, From, Into, new)]
14pub struct GenParams {
15    #[clap(long, default_value = "0", help_heading = "Generation Parameters")]
16    seed: u64,
17    #[clap(long, default_value = "0.7", help_heading = "Generation Parameters")]
18    cell_prob: f64,
19    #[clap(long, default_value = "70x40", help_heading = "Generation Parameters")]
20    grid_size: Bounds,
21}
22
23impl GenParams {
24    /// Generate the initial state from the parameters
25    pub fn generate_state(self) -> State {
26        let mut rng = StdRng::seed_from_u64(self.seed);
27        self.sample(&mut rng)
28    }
29}
30
31impl Distribution<State> for GenParams {
32    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> State {
33        State::new(0, self.sample(rng))
34    }
35}
36
37impl Distribution<ConwaysLife> for GenParams {
38    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> ConwaysLife {
39        let g: Generation = self.sample(rng);
40        ConwaysLife::new(g)
41    }
42}
43
44impl Distribution<Generation> for GenParams {
45    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Generation {
46        let area = self.grid_size.area();
47        let mut cells = Vec::with_capacity(area);
48        for _ in 0..area {
49            cells.push(self.sample(rng));
50        }
51
52        Generation::new(self.grid_size, cells)
53    }
54}
55
56impl Distribution<Cell> for GenParams {
57    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Cell {
58        Cell::from(rng.random_bool(self.cell_prob))
59    }
60}