gol_core/evolution/
strategy_discrete.rs

1use crate::{EvolutionStrategy, IndexedDataOwned};
2use num_traits::{FromPrimitive, PrimInt, Unsigned};
3use std::collections::HashSet;
4
5pub struct DecayMultiAliveStrategy {
6    state_count: usize,
7    alive_surive_counts: HashSet<usize>,
8    newborn_counts: HashSet<usize>,
9}
10
11impl<CI, T, I> EvolutionStrategy<CI, T, I> for DecayMultiAliveStrategy
12where
13    T: PrimInt + Unsigned + FromPrimitive + std::ops::Sub<Output = T>,
14    I: Iterator<Item = IndexedDataOwned<CI, T>>,
15{
16    fn next_state(&self, _: CI, cur_state: T, neighbors: I) -> T {
17        let mut alive_count = 0;
18        for (_, state) in neighbors {
19            alive_count += if state <= T::zero() { 0 } else { 1 };
20        }
21
22        let is_alive = cur_state > T::zero();
23        if is_alive && !self.alive_surive_counts.contains(&alive_count) {
24            cur_state - T::one()
25        } else if !is_alive && self.newborn_counts.contains(&alive_count) {
26            T::from_usize(self.state_count).unwrap() - T::one()
27        } else {
28            cur_state
29        }
30    }
31}
32
33impl DecayMultiAliveStrategy {
34    pub fn new(
35        state_count: usize,
36        alive_surive_counts: HashSet<usize>,
37        newborn_counts: HashSet<usize>,
38    ) -> Self {
39        Self {
40            state_count,
41            alive_surive_counts,
42            newborn_counts,
43        }
44    }
45}