Created
July 24, 2017 18:54
-
-
Save biern/c1b5621f13be9e6a96114863a8f6ff1b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Life.Game do | |
@type cell :: {integer, integer} | |
@type state :: [cell] | |
@adjacency_offsets [ | |
{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, | |
{0, 1}, {1, -1}, {1, 0}, {1, 1}, | |
] | |
@spec next(state) :: state | |
def next(state) do | |
state | |
|> Enum.flat_map(&get_neighbours/1) | |
|> MapSet.new |> MapSet.union(MapSet.new(state)) | |
|> Enum.filter(fn cell -> should_live(state, cell) end) | |
end | |
@spec get_neighbours(cell) :: state | |
def get_neighbours({cx, cy}) do | |
@adjacency_offsets | |
|> Enum.map(fn {dx, dy} -> {cx + dx, cy + dy} end) | |
end | |
@spec should_live(state, cell) :: boolean | |
def should_live(state, cell) do | |
alive = cell in state | |
case get_alive_neighbours(state, cell) do | |
2 -> alive | |
3 -> true | |
_ -> false | |
end | |
end | |
@spec get_alive_neighbours(state, cell) :: integer | |
def get_alive_neighbours(state, {cx, cy}) do | |
@adjacency_offsets | |
|> Enum.reduce(0, fn {dx, dy}, acc -> | |
alive = {dx + cx, dy + cy} in state | |
acc + if alive, do: 1, else: 0 | |
end) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment