From 3da437c4ba8920d932fb73b984aae1032947ebd3 Mon Sep 17 00:00:00 2001 From: mehbark <terezi@pyrope.net> Date: Tue, 11 Mar 2025 16:59:25 -0400 Subject: [PATCH] image sequence --- src/main.rs | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index 09073c6..13ba984 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,9 +12,7 @@ const TYPE_COLORS_SRC: &str = include_str!("type-colors.json"); use std::{ collections::{HashMap, HashSet}, - fmt, - path::PathBuf, - process, + fmt, process, }; use clap::Parser; @@ -26,27 +24,33 @@ use rand::{ }; use serde::Deserialize; +// i'm putting my foot down +const OUTPUT_DIGITS: usize = 5; + fn main() { let Args { width, height, - output_file, + output_prefix, steps, } = Args::parse(); let mut rng = rand::rng(); let mut game = Game::new_random(width, height, &mut rng); - for _ in 0..steps { + for i in 0..steps { game.step(&mut rng); + + let path = format!("{output_prefix}{i:0OUTPUT_DIGITS$}.png"); + if let Err(e) = ImageBuffer::from(&game).save(path) { + eprintln!("error saving image: {e}"); + process::exit(1); + } } // TODO: refactor to error enum to avoid this // TODO: animation (at least fast image sequence) + // TODO: don't constantly alloc buffers // if we need more errors - if let Err(e) = ImageBuffer::from(game).save(output_file) { - eprintln!("error saving image: {e}"); - process::exit(1); - } } lazy_static! { @@ -68,11 +72,16 @@ lazy_static! { } #[derive(Debug, clap::Parser)] +#[command(version, about, long_about = None)] struct Args { + /// Width of the output images (pixel-widths) width: u16, + /// Width of the output images (pixel-widths) height: u16, + /// Prefix for image paths; ex: /tmp/example- -> /tmp/example-000.png ... #[arg(short, long)] - output_file: PathBuf, + output_prefix: String, + /// How many steps to run the automata #[arg(short, long)] steps: u64, } @@ -142,8 +151,8 @@ impl Game { } } -impl From<Game> for ImageBuffer<Rgb<u8>, Vec<u8>> { - fn from(val: Game) -> Self { +impl From<&Game> for ImageBuffer<Rgb<u8>, Vec<u8>> { + fn from(val: &Game) -> Self { ImageBuffer::from_fn(val.width as u32, val.height as u32, |x, y| { val.at(i64::from(x), i64::from(y)).unwrap().color() })