40 lines
1.3 KiB
Rust
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)
|
|
}
|
|
}
|