automata.rs

2.5 kB · rust · 68 lines

1use crate::Grid;2use mrlycore::{json, Json, Rng, Tensor};3use mrlymath::life::elementary;4use wasm_bindgen::prelude::*;56fn diagram(cells: Tensor) -> Grid {7    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.15#[wasm_bindgen]16pub fn eca_next(row: &[u8], rule: u8, wrap: bool) -> Vec<u8> {17    elementary::step(row, rule, wrap)18}1920/// Draws the space-time diagram of a seed row: row 0 the seed, then one row per generation.21#[wasm_bindgen]22pub fn eca_history(row: &[u8], rule: u8, steps: usize, wrap: bool) -> Grid {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) -> Grid {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),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}