get/set/do prefix notation.
[cellular-automata.git] / 002 / src / life.ml
index 58ffbca..f7bf55e 100644 (file)
@@ -6,6 +6,19 @@ let directions =
   [N; NE; E; SE; S; SW; W; NW]
 
 
+let (|>) x f = f x
+
+
+let char_dead  = ' '
+let char_alive = 'o'
+
+
+let char_of_state = function
+  | 0 -> char_dead
+  | 1 -> char_alive
+  | _ -> assert false
+
+
 let offset = function
   (* direction -> x, y *)
   | N  ->  0, -1
@@ -24,11 +37,19 @@ let minisleep subsec =
 
 
 let init_board x y =
-  Array.map (Array.map (fun _ -> Random.int 2)) (Array.make_matrix x y 0)
+  Array.map (Array.map (fun _ -> Random.int 2)) (Array.make_matrix y x 0)
 
 
 let print_board board =
-  Array.iter (fun row -> Array.iter (print_int) row; print_newline ()) board
+  Array.iter
+  (
+    fun row ->
+      Array.iter
+      (fun state -> print_char (char_of_state state))
+      row;
+      print_newline ()
+  )
+  board
 
 
 let new_state = function
@@ -45,27 +66,29 @@ let filter_offsides width height neighbors =
   neighbors
 
 
+let neighbors x y =
+  List.map
+  (
+    fun d ->
+      let off_x, off_y = offset d in
+      (x + off_x), (y + off_y)
+  )
+  directions
+
+
 let new_generation board =
-  let height = Array.length board
-  and width = Array.length board.(0) in
+  let h = Array.length board
+  and w = Array.length board.(0) in
   Array.mapi
   (
-    fun i_y row ->
+    fun y row ->
       Array.mapi
-      (fun i_x state->
-        let neighbors =
-          List.map
-          (fun d ->
-            let off_x, off_y = offset d in
-            (i_x + off_x), (i_y + off_y)
-          )
-          directions
-        in
-        let neighbors = filter_offsides width height neighbors in
-        let states = List.map (fun (x, y) -> board.(y).(x)) neighbors in
-        let live_neighbors = List.fold_left (+) 0 states in
-        let state = new_state (state, live_neighbors) in
-        state
+      (
+        fun x state->
+          let neighbors = neighbors x y |> filter_offsides w h in
+          let states = List.map (fun (x, y) -> board.(y).(x)) neighbors in
+          let live_neighbors = List.fold_left (+) 0 states in
+          new_state (state, live_neighbors)
       )
       row
   )
@@ -79,10 +102,14 @@ let rec life_loop board =
   life_loop (new_generation board)
 
 
-let main x y =
+let main argv =
+  let x = int_of_string argv.(1)
+  and y = int_of_string argv.(2)
+  in
+
   Random.init (int_of_float (Unix.time ()));
 
   life_loop (init_board x y)
 
 
-let () = main 61 236
+let () = main Sys.argv
This page took 0.040117 seconds and 4 git commands to generate.