Skip to content

Instantly share code, notes, and snippets.

@proglottis
Created August 29, 2012 11:57
Show Gist options
  • Save proglottis/3511496 to your computer and use it in GitHub Desktop.
Save proglottis/3511496 to your computer and use it in GitHub Desktop.
Life
-module(life).
-export([life/2, new/2, randomize/1, step/1, print/1]).
-record(board, {width, height, cells, generation=0}).
life(Width, Height) ->
life(new(Width, Height)).
life(Board) ->
receive
print ->
life(print(Board));
generation ->
life(print_generation(Board));
step ->
life(step(Board));
randomize ->
life(randomize(Board));
Unexpected ->
io:format("unexpected message ~p~n", [Unexpected])
end.
new(Width, Height) ->
#board{width=Width, height=Height,
cells=lists:duplicate(Width * Height, 0)}.
randomize(Board) ->
Board#board{cells=[random:uniform(2) - 1 || _ <- Board#board.cells],
generation=0}.
map(Board, Fun) ->
map(Board, Fun, []).
map(Board, Fun, []) ->
map(Board, Fun, [Fun(lists:nth(1, Board#board.cells), 0, 0)]);
map(Board, _Fun, Acc) when length(Acc) >= length(Board#board.cells) ->
Board#board{cells=lists:reverse(Acc),
generation=Board#board.generation + 1};
map(Board, Fun, Acc) ->
Y=trunc(length(Acc) / Board#board.width),
X=(Y * Board#board.width - length(Acc)) * -1,
Cell=lists:nth(length(Acc) + 1, Board#board.cells),
map(Board, Fun, [Fun(Cell, X, Y)|Acc]).
cell(_Board, X, _Y) when X < 0 -> 0;
cell(_Board, _X, Y) when Y < 0 -> 0;
cell(Board, X, _Y) when X >= Board#board.width -> 0;
cell(Board, _X, Y) when Y >= Board#board.height -> 0;
cell(Board, X, Y) ->
lists:nth(Y * Board#board.width + X + 1, Board#board.cells).
count_neighbours(Board, X, Y) ->
lists:sum([cell(Board, X-1, Y-1),
cell(Board, X-1, Y),
cell(Board, X-1, Y+1),
cell(Board, X, Y-1),
cell(Board, X, Y+1),
cell(Board, X+1, Y-1),
cell(Board, X+1, Y),
cell(Board, X+1, Y+1)]).
check_cell(1, 2) -> 1;
check_cell(1, 3) -> 1;
check_cell(0, 3) -> 1;
check_cell(_, _) -> 0.
step(Board) ->
map(Board,
fun (Cell, X, Y) ->
Neighbours = count_neighbours(Board, X, Y),
check_cell(Cell, Neighbours)
end).
row(Board, Y) ->
Offset = Y * Board#board.width + 1,
lists:sublist(Board#board.cells, Offset, Board#board.width).
print(Board) ->
lists:foreach(
fun(Y) ->
io:format("[~s]~n", [lists:map(fun cell_char/1, row(Board, Y))])
end, lists:seq(0, Board#board.height - 1)),
Board.
print_generation(Board) ->
io:format("Generation: ~B~n", [Board#board.generation]),
Board.
cell_char(0) -> " ";
cell_char(_) -> "X".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment