From 727f4f295709853b11c6ad3f667c62c93564c4a4 Mon Sep 17 00:00:00 2001
From: mehbark <terezi@pyrope.net>
Date: Tue, 11 Mar 2025 18:14:31 -0400
Subject: [PATCH] some optimization

---
 src/main.rs | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index adc6ed4..b554087 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -30,14 +30,17 @@ fn main() {
 
     let mut game = Game::new_random(width, height, &mut rng);
     let mut last = game.clone();
+
+    let mut buffer = ImageBuffer::new(u32::from(width), u32::from(height));
+
     for i in 0..steps {
         let GameStep { old, new } = game.step(last, &mut rng);
         game = new;
         last = old;
 
+        game.write_to_buffer(&mut buffer);
         let path = format!("{output_prefix}{i:0OUTPUT_DIGITS$}.png");
-        // TODO: reuse `ImageBuffer`
-        if let Err(e) = ImageBuffer::from(&game).save(path) {
+        if let Err(e) = buffer.save(path) {
             eprintln!("error saving image: {e}");
             process::exit(1);
         }
@@ -116,7 +119,13 @@ impl Game {
                 let Some(other) = self.at(ox, oy) else {
                     continue;
                 };
+
                 let here = self.at(x, y).unwrap();
+
+                if other == here {
+                    continue;
+                }
+
                 let won = rng.random::<f32>() <= here.win_chance(other);
                 if won {
                     next.set(ox, oy, here);
@@ -130,13 +139,15 @@ impl Game {
             new: next,
         }
     }
-}
 
-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()
-        })
+    fn write_to_buffer(&self, buffer: &mut ImageBuffer<Rgb<u8>, Vec<u8>>) {
+        assert_eq!(self.width as u32, buffer.width());
+        assert_eq!(self.height as u32, buffer.height());
+        for x in 0..self.width {
+            for y in 0..self.height {
+                buffer[(x as u32, y as u32)] = self.at(x, y).unwrap().color();
+            }
+        }
     }
 }
 
@@ -228,10 +239,10 @@ impl Type {
             (Strong, Strong) | (Neutral, Neutral) | (Weak, Weak) | (Immune, Immune) => 0.5,
             (Immune, _) => 1.0,
             (_, Immune) => 0.0,
-            (Efficacy::Strong, Efficacy::Neutral) | (Efficacy::Neutral, Efficacy::Weak) => 2. / 3.,
-            (Efficacy::Neutral, Efficacy::Strong) | (Efficacy::Weak, Efficacy::Neutral) => 1. / 3.,
-            (Efficacy::Strong, Efficacy::Weak) => 4. / 5.,
-            (Efficacy::Weak, Efficacy::Strong) => 1. / 5.,
+            (Strong, Neutral) | (Neutral, Weak) => 2. / 3.,
+            (Neutral, Strong) | (Weak, Neutral) => 1. / 3.,
+            (Strong, Weak) => 4. / 5.,
+            (Weak, Strong) => 1. / 5.,
         }
     }