| 1 | // Tape runner for the Rust pet core. |
| 2 | // petsim — run tape.tsv on stdin, print digests |
| 3 | // petsim --frame N WxH — print the braille frame at tape frame N |
| 4 | // |
| 5 | // Build: rustc -O main.rs -o petsim (zero dependencies) |
| 6 | use std::io::Read; |
| 7 | |
| 8 | #[path = "pet_sim.rs"] |
| 9 | mod pet_sim; |
| 10 | use pet_sim::*; |
| 11 | |
| 12 | fn parse_row(c: Vec<&str>) -> Option<(f64, PetState)> { |
| 13 | if c.len() < 10 || c[0] == "dt" { return None; } |
| 14 | let channel = ChannelId::from_key(c[4]).expect("known tape channel"); |
| 15 | Some((c[0].parse().unwrap(), PetState { |
| 16 | activity: c[1].parse().unwrap(), coherence: c[2].parse().unwrap(), |
| 17 | attention: c[3].parse().unwrap(), channel, |
| 18 | observed: c[5].parse().unwrap(), roam_x: c[6].parse().unwrap(), |
| 19 | roam_y: c[7].parse().unwrap(), flip: c[8].parse().unwrap(), lit: c[9].parse().unwrap(), |
| 20 | })) |
| 21 | } |
| 22 | |
| 23 | fn main() { |
| 24 | let args: Vec<String> = std::env::args().collect(); |
| 25 | let motion = !args.iter().any(|s| s == "--reduced-motion"); |
| 26 | let mut tape = String::new(); |
| 27 | std::io::stdin().read_to_string(&mut tape).unwrap(); |
| 28 | let rows: Vec<(f64, PetState)> = |
| 29 | tape.trim().lines().filter_map(|l| parse_row(l.split('\t').collect())).collect(); |
| 30 | |
| 31 | let mut sim = if args.iter().any(|s| s == "--legacy") { PetSim::legacy_whale() } else { PetSim::whale() }; |
| 32 | |
| 33 | if args.get(1).map(|s| s.as_str()) == Some("--frame") { |
| 34 | let target: usize = args[2].parse().unwrap(); |
| 35 | let (cw, ch) = if args.len() > 3 { |
| 36 | let mut d = args[3].split('x'); |
| 37 | (d.next().unwrap().parse().unwrap(), d.next().unwrap().parse().unwrap()) |
| 38 | } else { (78, 26) }; |
| 39 | let mut st = PetState::rest(); |
| 40 | for (i, (dt, s)) in rows.iter().enumerate() { |
| 41 | sim.step(*dt, s, motion, 1.0); |
| 42 | if i == target { st = *s; break; } |
| 43 | } |
| 44 | print!("{}", braille_text(&braille(&sim, cw, ch, &st), cw, ch)); |
| 45 | return; |
| 46 | } |
| 47 | |
| 48 | let mut out = String::new(); |
| 49 | for (i, (dt, st)) in rows.iter().enumerate() { |
| 50 | sim.step(*dt, st, motion, 1.0); |
| 51 | if i % 30 == 0 { |
| 52 | out.push_str(&format!("f{:04} {} {}\n", i, digest(&sim), st.channel)); |
| 53 | } |
| 54 | } |
| 55 | out.push_str(&format!("final {}", digest(&sim))); |
| 56 | println!("{}", out); |
| 57 | } |
| 58 |