Traditional, matrix approach in OCaml. Unpolished.
authorSiraaj Khandkar <siraaj@khandkar.net>
Mon, 6 Aug 2012 14:49:16 +0000 (10:49 -0400)
committerSiraaj Khandkar <siraaj@khandkar.net>
Mon, 6 Aug 2012 14:49:16 +0000 (10:49 -0400)
.gitignore
002/Makefile [new file with mode: 0644]
002/src/life.ml [new file with mode: 0644]

index 6423164..a59e13c 100644 (file)
@@ -1,6 +1,9 @@
 .eunit
+bin
 deps
 priv
 *.o
 *.beam
-*.plt
\ No newline at end of file
+*.plt
+*.cmi
+*.cmx
diff --git a/002/Makefile b/002/Makefile
new file mode 100644 (file)
index 0000000..54a1aee
--- /dev/null
@@ -0,0 +1,18 @@
+COMPILER="ocamlopt"
+OBJ_EXT="cmx"
+
+
+compile:
+       @mkdir -p bin
+       @ocamlfind $(COMPILER) -linkpkg -package unix \
+           -o bin/life \
+              src/life.ml
+
+
+clean:
+       @rm -rf bin
+       @find ./src \
+               -name \*.o \
+           -or -name \*.cmi \
+           -or -name \*.$(OBJ_EXT) \
+           | xargs rm -f
diff --git a/002/src/life.ml b/002/src/life.ml
new file mode 100644 (file)
index 0000000..58ffbca
--- /dev/null
@@ -0,0 +1,88 @@
+type direction =
+  N | NE | E | SE | S | SW | W | NW
+
+
+let directions =
+  [N; NE; E; SE; S; SW; W; NW]
+
+
+let offset = function
+  (* direction -> x, y *)
+  | N  ->  0, -1
+  | NE ->  1, -1
+  | E  ->  1,  0
+  | SE ->  1,  1
+  | S  ->  0,  1
+  | SW -> -1,  1
+  | W  -> -1,  0
+  | NW -> -1, -1
+
+
+(* Hack to sleep less than 1 sec *)
+let minisleep subsec =
+  ignore (Unix.select [] [] [] subsec)
+
+
+let init_board x y =
+  Array.map (Array.map (fun _ -> Random.int 2)) (Array.make_matrix x y 0)
+
+
+let print_board board =
+  Array.iter (fun row -> Array.iter (print_int) row; print_newline ()) board
+
+
+let new_state = function
+  | 1, live_neighbors when live_neighbors < 2 -> 0
+  | 1, live_neighbors when live_neighbors < 4 -> 1
+  | 1, live_neighbors when live_neighbors > 3 -> 0
+  | 0, live_neighbors when live_neighbors = 3 -> 1
+  | state, _ -> state
+
+
+let filter_offsides width height neighbors =
+  List.filter
+  (fun (x, y) -> x >= 0 && y >= 0 && x < width && y < height)
+  neighbors
+
+
+let new_generation board =
+  let height = Array.length board
+  and width = Array.length board.(0) in
+  Array.mapi
+  (
+    fun i_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
+      )
+      row
+  )
+  board
+
+
+let rec life_loop board =
+  print_board board;
+  print_newline ();
+  minisleep 0.1;
+  life_loop (new_generation board)
+
+
+let main x y =
+  Random.init (int_of_float (Unix.time ()));
+
+  life_loop (init_board x y)
+
+
+let () = main 61 236
This page took 0.020849 seconds and 4 git commands to generate.