Skip to content

Instantly share code, notes, and snippets.

@biern
Created July 24, 2017 18:54
Show Gist options
  • Save biern/c1b5621f13be9e6a96114863a8f6ff1b to your computer and use it in GitHub Desktop.
Save biern/c1b5621f13be9e6a96114863a8f6ff1b to your computer and use it in GitHub Desktop.
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