Traditional, matrix approach in OCaml. Unpolished.
[cellular-automata.git] / 002 / src / life.ml
1 type direction =
2 N | NE | E | SE | S | SW | W | NW
3
4
5 let directions =
6 [N; NE; E; SE; S; SW; W; NW]
7
8
9 let offset = function
10 (* direction -> x, y *)
11 | N -> 0, -1
12 | NE -> 1, -1
13 | E -> 1, 0
14 | SE -> 1, 1
15 | S -> 0, 1
16 | SW -> -1, 1
17 | W -> -1, 0
18 | NW -> -1, -1
19
20
21 (* Hack to sleep less than 1 sec *)
22 let minisleep subsec =
23 ignore (Unix.select [] [] [] subsec)
24
25
26 let init_board x y =
27 Array.map (Array.map (fun _ -> Random.int 2)) (Array.make_matrix x y 0)
28
29
30 let print_board board =
31 Array.iter (fun row -> Array.iter (print_int) row; print_newline ()) board
32
33
34 let new_state = function
35 | 1, live_neighbors when live_neighbors < 2 -> 0
36 | 1, live_neighbors when live_neighbors < 4 -> 1
37 | 1, live_neighbors when live_neighbors > 3 -> 0
38 | 0, live_neighbors when live_neighbors = 3 -> 1
39 | state, _ -> state
40
41
42 let filter_offsides width height neighbors =
43 List.filter
44 (fun (x, y) -> x >= 0 && y >= 0 && x < width && y < height)
45 neighbors
46
47
48 let new_generation board =
49 let height = Array.length board
50 and width = Array.length board.(0) in
51 Array.mapi
52 (
53 fun i_y row ->
54 Array.mapi
55 (fun i_x state->
56 let neighbors =
57 List.map
58 (fun d ->
59 let off_x, off_y = offset d in
60 (i_x + off_x), (i_y + off_y)
61 )
62 directions
63 in
64 let neighbors = filter_offsides width height neighbors in
65 let states = List.map (fun (x, y) -> board.(y).(x)) neighbors in
66 let live_neighbors = List.fold_left (+) 0 states in
67 let state = new_state (state, live_neighbors) in
68 state
69 )
70 row
71 )
72 board
73
74
75 let rec life_loop board =
76 print_board board;
77 print_newline ();
78 minisleep 0.1;
79 life_loop (new_generation board)
80
81
82 let main x y =
83 Random.init (int_of_float (Unix.time ()));
84
85 life_loop (init_board x y)
86
87
88 let () = main 61 236
This page took 0.077799 seconds and 4 git commands to generate.