-define(CHAR_ALIVE, 111). % "o"
-define(CHAR_BAR, 45). % "-"
--define(INTERVAL, 100).
+-define(GEN_INTERVAL, 100).
-record(state, {x :: non_neg_integer()
,y :: non_neg_integer()
,n :: pos_integer()
- ,bar :: string()
+ ,bar :: nonempty_string()
,board :: array()
,gen_count :: pos_integer()
,gen_duration :: non_neg_integer()
end
),
- {NewTime, NewBoard} = timer:tc(fun() -> next_generation(X, Y, Board) end),
+ {NewTime, NewBoard} = timer:tc(
+ fun() ->
+ next_generation(X, Y, Board)
+ end
+ ),
+
NewState = State#state{board = NewBoard
,gen_count = GenCount + 1
,gen_duration = NewTime
,print_time = PrintTime
},
- timer:sleep(?INTERVAL),
+ NewTimeMil = NewTime / 1000,
+ NextGenDelay = at_least_zero(round(?GEN_INTERVAL - NewTimeMil)),
+ timer:sleep(NextGenDelay),
+
life_loop(NewState).
+at_least_zero(Integer) when Integer >= 0 -> Integer;
+at_least_zero(_) -> 0.
+
+
do_print_screen(Board, Bar, X, Y, N, GenCount, Time, PrintTime) ->
ok = do_print_status(Bar, X, Y, N, GenCount, Time, PrintTime),
ok = do_print_board(Board).
do_print_board(Board) ->
- CharLists = array:to_list(
+ % It seems that just doing a fold should be faster than map + to_list
+ % combo, but, after measuring several times, map + to_list has been
+ % consistently (nearly twice) faster than either foldl or foldr.
+ RowStrings = array:to_list(
array:map(
fun(_, Row) ->
array:to_list(
),
ok = lists:foreach(
- fun(CharList) ->
- ok = io:format("~s~n", [CharList])
+ fun(RowString) ->
+ ok = io:format("~s~n", [RowString])
end,
- CharLists
+ RowStrings
).