-life_loop(X, Y, Board) ->
- ok = do_print_board(Board),
- timer:sleep(?INTERVAL),
- life_loop(X, Y, next_generation(X, Y, Board)).
+life_loop(
+ #state{x = X
+ ,y = Y
+ ,n = N
+ ,bar = Bar
+ ,board = Board
+ ,gen_count = GenCount
+ ,gen_duration = Time
+ ,print_time = LastPrintTime
+ }=State) ->
+
+ {PrintTime, ok} = timer:tc(
+ fun() ->
+ do_print_screen(Board, Bar, X, Y, N, GenCount, Time, LastPrintTime)
+ 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
+ },
+
+ 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_status(Bar, X, Y, N, GenCount, TimeMic, PrintTimeMic) ->
+ TimeSec = TimeMic / 1000000,
+ PrintTimeSec = PrintTimeMic / 1000000,
+ ok = io:format("~s~n", [Bar]),
+ ok = io:format(
+ "X: ~b Y: ~b CELLS: ~b GENERATION: ~b DURATION: ~f PRINT TIME: ~f~n",
+ [X, Y, N, GenCount, TimeSec, PrintTimeSec]
+ ),
+ ok = io:format("~s~n", [Bar]).