Conway's Game of Life in Erlang, in 2 hours, with 0 Erlang experience, in 20 lines of code.
1337 h4x0rs:
- @jszmajda
- @ngauthier
- @ericoestrich
- @danivovich
- @kafuchau
Later refactored and enhanced by @seancribbs
| -module(gol). | |
| -export([transmute_world/1, display/1, run/2]). | |
| lives(2,true) -> | |
| true; | |
| lives(3,_) -> | |
| true; | |
| lives(_,_) -> | |
| false. | |
| %% neighbors1(Xin,Yin, World) -> | |
| %% length([ | |
| %% true || {X, Y, true} <- World, | |
| %% X >= Xin - 1, X <= Xin + 1, | |
| %% Y >= Yin - 1, Y <= Yin + 1, | |
| %% not (X == Xin andalso Y == Yin) | |
| %% ]). | |
| neighbors2(Xin, Yin, World) -> | |
| Neighbors = [ {Xin + X, Yin + Y} || | |
| X <- [-1, 0, 1], | |
| Y <- [-1, 0, 1], | |
| not (X == 0 andalso Y == 0)], | |
| length([ true || {X, Y} <- Neighbors, | |
| {XW, YW, true} <- World, | |
| X == XW andalso Y == YW]). | |
| transmute_world(World) -> | |
| [ {X, Y, lives(neighbors2(X,Y, World), Alive)} || {X,Y,Alive} <- World ]. | |
| sort_by_rows({_, Y0, _}, {_, Y1, _}) when Y0 < Y1 -> | |
| true; | |
| sort_by_rows({X0, Y, _}, {X1, Y, _}) when X0 < X1 -> | |
| true; | |
| sort_by_rows(_, _) -> false. | |
| cell_to_display_fold({_X, Y, Alive}, {Row, Output}) -> | |
| Char = case Alive of | |
| true -> $X; | |
| false -> $. | |
| end, | |
| case Row of | |
| Y -> {Row, [Char|Output]}; | |
| _ -> {Y, [Char, $\n| Output]} | |
| end. | |
| display(World) -> | |
| %% sort by Y so we get rows together | |
| World1 = lists:sort(fun sort_by_rows/2, World), | |
| %% Turn the true/false into strings for output, adding line returns after rows | |
| {_Row, Output} = lists:foldl(fun cell_to_display_fold/2, {0, []}, World1), | |
| %% Clear the screen and print the board at the top left. | |
| io:format("\e[2J\e[0;0H~ts~n", [lists:reverse(Output)]). | |
| run(World, None) when None =< 0 -> | |
| World; | |
| run(World, Iters) -> | |
| display(World), | |
| timer:sleep(500), | |
| run(transmute_world(World), Iters - 1). |