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}