models.rs
2.2 kB · rust · 75 lines
1use super::sequence::Counts;2use super::{Boundary, Fate};3use crate::two::Cell2d;4use mrlycore::errors::Result;56/// The rulebook of a life run.7#[derive(Clone, Debug)]8pub struct Config {9 /// The neighborhood mask.10 pub mask: Cell2d,11 /// The neighbor counts that create a cell.12 pub birth: Counts,13 /// The neighbor counts that keep a cell.14 pub survive: Counts,15 /// The edge policy.16 pub boundary: Boundary,17 /// The generation cap.18 pub max_generations: usize,19 /// The tiling factor applied to the seed.20 pub grid_size: usize,21 /// The dead border added around the seed.22 pub padding: usize,23}2425impl Config {26 /// Builds a config with a constant boundary, a 64-generation cap, no tiling and no padding.27 pub fn new(mask: Cell2d, birth: impl Into<Counts>, survive: impl Into<Counts>) -> Config {28 Config {29 mask,30 birth: birth.into(),31 survive: survive.into(),32 boundary: Boundary::Constant,33 max_generations: 64,34 grid_size: 1,35 padding: 0,36 }37 }38 /// Returns the largest neighbor count the mask can reach.39 pub fn budget(&self) -> usize {40 self.mask.types().sum() as usize41 }42 /// Resolves the birth and survive counts against the mask's budget.43 pub fn counts(&self) -> Result<(Vec<usize>, Vec<usize>)> {44 let budget = self.budget();45 Ok((self.birth.values(budget)?, self.survive.values(budget)?))46 }47}4849/// The recorded run of one seed.50#[derive(Clone, Debug)]51pub struct Life {52 /// Every generation in order.53 pub grids: Vec<Cell2d>,54 /// The run's ending.55 pub fate: Fate,56 /// The number of recorded generations.57 pub count: usize,58 /// The cycle length when the fate is a loop, else zero.59 pub loop_length: usize,60}6162impl Life {63 /// Returns the final grid, or None when the run is empty.64 pub fn last(&self) -> Option<&Cell2d> {65 self.grids.last()66 }67 /// Returns the index of the first frame.68 pub fn first_frame_idx(&self) -> usize {69 070 }71 /// Returns the index of the last frame.72 pub fn last_frame_idx(&self) -> usize {73 self.grids.len().saturating_sub(1)74 }75}