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}