Organize transition mechanism into Automaton module
[cellular-automata.git] / polymorphic-life / 001 / src / polymorphic_life.ml
index a5e39c0..5835ff2 100644 (file)
@@ -8,15 +8,15 @@ module type MATRIX = sig
 
   type 'a t
 
-  val create : rs:int -> ks:int -> data:'a -> 'a t
+  val create : rs:int -> ks:int -> 'a -> 'a t
 
   val get_neighbors : 'a t -> Point.t -> 'a list
 
   val map : 'a t -> f:('a -> 'b) -> 'b t
 
-  val mapi : 'a t -> f:(Point.t -> data:'a -> 'b) -> 'b t
+  val mapi : 'a t -> f:(Point.t -> 'a -> 'b) -> 'b t
 
-  val iter : 'a t -> f:(Point.t -> data:'a -> unit) -> unit
+  val iter : 'a t -> f:(Point.t -> 'a -> unit) -> unit
 
   val print : 'a t -> to_string:('a -> string) -> unit
 end
@@ -56,15 +56,15 @@ module Matrix : MATRIX = struct
 
   type 'a t = 'a array array
 
-  let create ~rs ~ks ~data =
-    Array.make_matrix ~dimx:rs ~dimy:ks data
+  let create ~rs ~ks x =
+    Array.make_matrix ~dimx:rs ~dimy:ks x
 
   let iter t ~f =
     Array.iteri t ~f:(
       fun r ks ->
         Array.iteri ks ~f:(
-          fun k data ->
-            f {Point.r; Point.k} ~data
+          fun k x ->
+            f {Point.r; Point.k} x
         )
     )
 
@@ -82,8 +82,8 @@ module Matrix : MATRIX = struct
     Array.mapi t ~f:(
       fun r ks ->
         Array.mapi ks ~f:(
-          fun k data ->
-            f {Point.r; Point.k} ~data
+          fun k x ->
+            f {Point.r; Point.k} x
         )
     )
 
@@ -153,28 +153,55 @@ module Conway : CELL = struct
 end
 
 
-let main rs ks () =
+module Automaton : sig
+  type t
+
+  val create : rows:int -> columns:int -> interval:float -> t
+
+  val loop : t -> unit
+end = struct
+  type t = { grid     : Conway.t Matrix.t
+           ; interval : Time.Span.t
+           ; bar      : string
+           }
+
+  let create ~rows:rs ~columns:ks ~interval =
+    { grid     = Matrix.map ~f:Conway.create (Matrix.create ~rs ~ks ())
+    ; interval = Time.Span.of_float interval
+    ; bar      = String.make ks '-'
+    }
+
+  let print t =
+    print_endline t.bar;
+    Matrix.print t.grid ~to_string:Conway.to_string;
+    print_endline t.bar
+
+  let next t =
+    let grid =
+      Matrix.mapi t.grid ~f:(
+        fun point cell ->
+          let neighbors = Matrix.get_neighbors t.grid point in
+          Conway.react cell ~states:(List.map neighbors ~f:Conway.state)
+      )
+    in
+    {t with grid}
+
+  let rec loop t =
+    print t;
+    Time.pause t.interval;
+    loop (next t)
+end
+
+
+let main () =
   Random.self_init ();
-  let grid = Matrix.create ~rs ~ks ~data:() |> Matrix.map ~f:Conway.create in
-  Matrix.print grid ~to_string:Conway.to_string;
-  print_endline (String.make 80 '-');
-  let grid =
-    Matrix.mapi grid ~f:(fun point ~data:cell ->
-      let neighbors = Matrix.get_neighbors grid point in
-      Conway.react cell ~states:(List.map neighbors ~f:Conway.state)
-    )
-  in
-  Matrix.print grid ~to_string:Conway.to_string
+  let rows, columns = Or_error.ok_exn Linux_ext.get_terminal_size () in
+  Automaton.create ~rows:(rows - 3) ~columns ~interval:0.1 |> Automaton.loop
 
 
 let spec =
   let summary = "Polymorphic Cellular Automata" in
-  let spec =
-    let open Command.Spec in
-    empty
-    +> flag "-rows" (optional_with_default 5 int) ~doc:"Height"
-    +> flag "-cols" (optional_with_default 5 int) ~doc:"Width"
-  in
+  let spec = Command.Spec.empty in
   Command.basic ~summary spec main
 
 
This page took 0.030262 seconds and 4 git commands to generate.