automata.rs

2.7 kB · rust · 68 lines

1use crate::{Fault, Grid};2use mrlyrs::core::{json, Json, Rng, Tensor};3use mrlyrs::life::elementary;4use wasm_bindgen::prelude::*;56fn diagram(cells: Tensor) -> Result<Grid, Fault> {7    Ok(Grid {8        width: cells.shape[1] as u32,9        height: cells.shape[0] as u32,10        types: cells.bytes()?.to_vec(),11    })12}1314/// Advances one row of the elementary rule one generation, a constant-0 boundary unless the edges wrap, or an error for a row that is not all bits.15#[wasm_bindgen]16pub fn eca_next(row: &[u8], rule: u8, wrap: bool) -> Result<Vec<u8>, Fault> {17    Ok(elementary::step(row, rule, wrap)?)18}1920/// Draws the space-time diagram of a seed row, row 0 the seed and then one row per generation, or an error for a row that is not all bits.21#[wasm_bindgen]22pub fn eca_history(row: &[u8], rule: u8, steps: usize, wrap: bool) -> Result<Grid, Fault> {23    diagram(elementary::history(row, rule, steps, wrap)?)24}2526/// Draws the single-seed diagram: one live cell run the given generations on a padded line, cropped back to the 2 steps + 1 window.27#[wasm_bindgen]28pub fn eca_seed(rule: u8, steps: usize) -> Result<Grid, Fault> {29    diagram(elementary::single_seed(rule, steps)?)30}3132/// Reads one rule's card: its name, corners, popcount, lambda, degree, genus, affine, surjective and reversible flags, outer-totalistic counts, cube class, Wolfram class, NPN representative and gasket, as JSON.33#[wasm_bindgen]34pub fn eca_card(rule: u8) -> String {35    let cube = elementary::cube_orbit(rule);36    let class = elementary::wolfram_class(rule);37    let totalistic = match elementary::outer_totalistic(rule) {38        Some((birth, survive)) => json!({"birth": birth, "survive": survive}),39        None => Json::Null,40    };41    json!({42        "rule": rule,43        "name": elementary::rule_name(rule).unwrap_or_default(),44        "corners": elementary::corner_bits(rule),45        "popcount": elementary::popcount(rule),46        "lambda": elementary::lambda(rule),47        "degree": elementary::rule_degree(rule),48        "genus": elementary::genus(rule),49        "affine": elementary::affine(rule),50        "surjective": elementary::surjective(rule),51        "reversible": elementary::reversible(rule),52        "outer_totalistic": totalistic,53        "b3_rep": cube[0],54        "b3_orbit": cube,55        "wolfram_class": class,56        "wolfram_rep": class[0],57        "npn_rep": elementary::npn_class(rule)[0],58        "gasket": elementary::gasket(rule),59    })60    .to_string()61}6263/// Draws a seeded row whose sites fill with the given chance.64#[wasm_bindgen]65pub fn eca_soup(width: usize, density: f64, seed: u32) -> Vec<u8> {66    let mut rng = Rng::new(seed as u64);67    (0..width).map(|_| u8::from(rng.chance(density))).collect()68}