X-Git-Url: https://git.xandkar.net/?a=blobdiff_plain;f=life%2F001%2Fsrc%2Flife.erl;fp=life%2F001%2Fsrc%2Flife.erl;h=2c0f3d338d6b97c5ddca8c4d6f8670ddfabf5ae7;hb=8d06c463b83b79e046250fbe60e5429f182e3a7a;hp=0000000000000000000000000000000000000000;hpb=4eb3be32ce405e69f39573b5e38171764cd0d789;p=cellular-automata.git diff --git a/life/001/src/life.erl b/life/001/src/life.erl new file mode 100644 index 0000000..2c0f3d3 --- /dev/null +++ b/life/001/src/life.erl @@ -0,0 +1,86 @@ +-module(life). +-behaviour(application). + + +%% API +-export([bang/0]). + +%% Callbacks +-export([start/2, stop/1]). + + +-define(DIRECTIONS, ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']). + + +%% ============================================================================ +%% API +%% ============================================================================ + +bang() -> + application:start(?MODULE). + + +%% ============================================================================ +%% Callbacks +%% ============================================================================ + +start(_StartType, _StartArgs) -> + {ok, X} = application:get_env(?MODULE, x), + {ok, Y} = application:get_env(?MODULE, y), + CellData = cell_data(X, Y), + life_god:start_link(X, Y, CellData). + + +stop(_State) -> + ok. + + +%% ============================================================================ +%% Internal +%% ============================================================================ + +cell_data(X, Y) -> + N = X * Y, + [cell_datum(X, N, ID) || ID <- lists:seq(1, N)]. + + +cell_datum(X, N, ID) -> + Name = integer_to_atom(ID), + NeighborNames = filter_offsides(N, + [integer_to_atom(neighbor_id(Dir, X, ID)) || Dir <- ?DIRECTIONS] + ), + {ID, Name, NeighborNames}. + + +neighbor_id(Direction, X, ID) -> ID + offset(Direction, X). + + +offset('N' , X) -> ensure_negative(X); +offset('NE', X) -> ensure_negative(X - 1); +offset('E' , _) -> 1; +offset('SE', X) -> X + 1; +offset('S' , X) -> X; +offset('SW', X) -> X - 1; +offset('W' , _) -> ensure_negative( 1); +offset('NW', X) -> ensure_negative(X + 1). + + +ensure_negative(N) when N < 0 -> N; +ensure_negative(N) -> -(N). + + +filter_offsides(N, IDs) -> + [ID || ID <- IDs, is_onside(N, atom_to_integer(ID))]. + + +is_onside(_, ID) when ID < 1 -> false; +is_onside(N, ID) when ID > N -> false; +is_onside(_, _) -> true. + + +atom_to_integer(Atom) -> + list_to_integer(atom_to_list(Atom)). + + +integer_to_atom(Integer) -> + list_to_atom(integer_to_list(Integer)).