use anyhow::anyhow; use rand::Rng; use crate::system::{GriddedPosition, Position, Storage}; pub trait Sticker> { fn should_stick(&self, rng: &mut R, space: &S, position: &P) -> bool; } pub struct SimpleSticking; pub struct ProbabilisticSticking { pub(crate) stick_probability: f32 } impl ProbabilisticSticking { pub fn new(stick_probability: f32) -> anyhow::Result { return if 0f32 < stick_probability && stick_probability <= 1f32 { Ok(ProbabilisticSticking { stick_probability }) } else { Err(anyhow!("Sticking probability outside of (0, 1] range.")) } } } impl> Sticker for SimpleSticking { fn should_stick(&self, _rng: &mut R, space: &S, position: &P) -> bool { (0..P::NEIGHBOURS) .map(|n| position.neighbour(n)) .any(|neighbour| space.is_occupied(&neighbour)) } } impl> Sticker for ProbabilisticSticking { fn should_stick(&self, rng: &mut R, space: &S, position: &P) -> bool { (0..P::NEIGHBOURS) .map(|n| position.neighbour(n)) .any(|neighbour| space.is_occupied(&neighbour) && rng.gen_range(0.0f32..=1.0) < self.stick_probability) } }