6 -define(CHAR_DEAD, 32). % " "
7 -define(CHAR_ALIVE, 111). % "o"
8 -define(INTERVAL, 100).
11 %% ============================================================================
13 %% ============================================================================
16 [X, Y] = [atom_to_integer(A) || A <- Args],
17 Board = init_board(X, Y),
21 %% ============================================================================
23 %% ============================================================================
26 ok = do_print_board(Board),
27 timer:sleep(?INTERVAL),
28 life_loop(next_generation(Board)).
31 do_print_board(Board) ->
32 CharLists = array:to_list(
50 ok = io:format("~s~n", [CharList])
56 state_to_char(0) -> ?CHAR_DEAD;
57 state_to_char(1) -> ?CHAR_ALIVE.
60 next_generation(Board) ->
61 H = array:size(Board),
62 W = array:size(array:get(0, Board)),
68 Neighbors = filter_offsides(H, W, neighbors(X, Y)),
69 States = neighbor_states(Board, Neighbors),
70 LiveNeighbors = lists:sum(States),
71 new_state(State, LiveNeighbors)
80 new_state(1, LiveNeighbors) when LiveNeighbors < 2 -> 0;
81 new_state(1, LiveNeighbors) when LiveNeighbors < 4 -> 1;
82 new_state(1, LiveNeighbors) when LiveNeighbors > 3 -> 0;
83 new_state(0, LiveNeighbors) when LiveNeighbors =:= 3 -> 1;
84 new_state(State, _LiveNeighbors) -> State.
87 neighbor_states(Board, Neighbors) ->
88 [array:get(X, array:get(Y, Board)) || {X, Y} <- Neighbors].
91 filter_offsides(H, W, Coordinates) ->
92 [{X, Y} || {X, Y} <- Coordinates, is_onside(X, Y, H, W)].
95 is_onside(X, Y, H, W) when (X >= 0) and (Y >= 0) and (X < W) and (Y < H) -> true;
96 is_onside(_, _, _, _) -> false.
100 [{X + OffX, Y + OffY} || {OffX, OffY} <- offsets()].
104 [offset(D) || D <- directions()].
107 offset('N') -> { 0, -1};
108 offset('NE') -> { 1, -1};
109 offset('E') -> { 1, 0};
110 offset('SE') -> { 1, 1};
111 offset('S') -> { 0, 1};
112 offset('SW') -> {-1, 1};
113 offset('W') -> {-1, 0};
114 offset('NW') -> {-1, -1}.
118 ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'].
122 array:map(fun(_, _) -> init_row(X) end, array:new(Y)).
126 array:map(fun(_, _) -> init_cell_state() end, array:new(X)).
130 crypto:rand_uniform(0, 2).
133 atom_to_integer(Atom) ->
134 list_to_integer(atom_to_list(Atom)).