Files
compb-dla-model/src/system/sticker.rs
T

40 lines
1.3 KiB
Rust

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