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()
         })