From 6ad01e280c032655ca0169b9488314d2275d1a59 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Am=C3=A9lia=20Coutard-Sander?= <git@ameliathe1st.gay>
Date: Sun, 12 Jan 2025 18:35:32 +0100
Subject: [PATCH] =?utf8?q?Meilleur=20it=C3=A9ration=20des=20cellules=20vis?=
 =?utf8?q?ibles=20du=20monde?=
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit

---
 automata/automata.ml  | 20 ++++++++++++++++++++
 automata/automata.mli |  2 ++
 bin/modes.ml          | 11 +++++------
 3 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/automata/automata.ml b/automata/automata.ml
index 57908a0..36ccf14 100644
--- a/automata/automata.ml
+++ b/automata/automata.ml
@@ -84,6 +84,26 @@ let set x y c (d, cells) =
                              Array.init chunk_size (fun y -> if x = ix && y = iy then c else d))))
             cells )
 
+let iter_range minx maxx miny maxy f (d, board) =
+        let mincx, minix = euclid_div minx chunk_size
+        and mincy, miniy = euclid_div miny chunk_size in
+        let maxcx, maxix = euclid_div maxx chunk_size
+        and maxcy, maxiy = euclid_div maxy chunk_size in
+        for cx = mincx to maxcx do
+          for cy = mincy to maxcy do
+            let get =
+                    match CoordMap.find_opt (cx, cy) board with
+                    | Some chunk -> fun x y -> chunk.(x).(y)
+                    | None -> fun _ _ -> d
+            in
+            for x = if cx = mincx then minix else 0 to if cx = maxcx then maxix else chunk_size - 1 do
+              for y = if cy = mincy then miniy else 0 to if cy = maxcy then maxiy else chunk_size - 1 do
+                f ((cx * chunk_size) + x) ((cy * chunk_size) + y) (get x y)
+              done
+            done
+          done
+        done
+
 let neighbour_chunks (x, y) =
         [
           (x - 1, y - 1);
diff --git a/automata/automata.mli b/automata/automata.mli
index 5f78a3f..0b62ffb 100644
--- a/automata/automata.mli
+++ b/automata/automata.mli
@@ -47,6 +47,8 @@ val get : int -> int -> 't board -> 't
 
 val set : int -> int -> 't -> 't board -> 't board
 
+val iter_range : int -> int -> int -> int -> (int -> int -> 't -> unit) -> 't board -> unit
+
 val update : (module Automaton with type t = 't) -> 't board -> 't board
 
 val automata : (module Automaton) list
diff --git a/bin/modes.ml b/bin/modes.ml
index f300fff..e7643dd 100644
--- a/bin/modes.ml
+++ b/bin/modes.ml
@@ -55,14 +55,13 @@ let render_world (EditorState (m, { board; pos = px, py; size })) =
         and h = (sy / size) + 1 in
         let wx = px - (w / 2)
         and wy = py - (h / 2) in
-        for x = wx to wx + w do
-          for y = wy to wy + h do
-            let r, g, b = M.color (Automata.get x y board) in
+        Automata.iter_range wx (wx + w) wy (wy + h)
+          (fun x y c ->
+            let r, g, b = M.color c in
             let r, g, b = (int_of_char r, int_of_char g, int_of_char b) in
             Graphics.set_color (Graphics.rgb r g b);
-            Graphics.fill_rect ((x - wx) * size) ((y - wy) * size) size size
-          done
-        done;
+            Graphics.fill_rect ((x - wx) * size) ((y - wy) * size) size size)
+          board;
         Graphics.set_color (Graphics.rgb 127 127 127);
         for x = 0 to w do
           Graphics.moveto (x * size) 0;
-- 
2.46.0