use crate::schedule::Schedule;
use crate::substrates::ca::rules::CARule;
use crate::substrates::ca::state::CAState;
use rand::Rng;
#[derive(Debug, Clone, Default)]
pub struct SynchronousCASchedule;
impl SynchronousCASchedule {
pub fn new() -> Self {
Self
}
}
impl<const N: usize, const R: usize> Schedule<CAState<N, R>, CARule<N, R>>
for SynchronousCASchedule
{
fn name(&self) -> &str {
"synchronous_ca"
}
fn timing(&self) -> &str {
"synchronous"
}
fn selection(&self) -> &str {
"exhaustive"
}
fn step(
&self,
state: &CAState<N, R>,
rules: &[CARule<N, R>],
_rng: &mut dyn Rng,
) -> CAState<N, R> {
if let Some(rule) = rules.first() {
rule.apply_sync(state)
} else {
state.clone()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::state::State;
use rand::{SeedableRng, rngs::StdRng};
#[test]
fn test_synchronous_schedule_applies_rule() {
let state = CAState::<8, 1>::new([1, 0, 0, 0, 0, 0, 0, 0]);
let rule = CARule::<8, 1>::from_wolfram_number(110);
let schedule = SynchronousCASchedule::new();
let mut rng = StdRng::seed_from_u64(42);
let next = schedule.step(&state, &[rule], &mut rng);
assert_eq!(next.cells()[0], 1);
assert_eq!(next.cells()[1], 0); }
#[test]
fn test_empty_rules_returns_clone() {
let state = CAState::<8, 1>::new([1, 0, 0, 0, 0, 0, 0, 0]);
let schedule = SynchronousCASchedule::new();
let mut rng = StdRng::seed_from_u64(42);
let next = schedule.step(&state, &[], &mut rng);
assert_eq!(next.canonical_encoding(), state.canonical_encoding());
}
}