gol_core/evolution/
strategy_discrete.rs1use 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}