Skip to content

Instantly share code, notes, and snippets.

@joemsak

joemsak/gol.exs

Forked from avdi/gol.exs
Created Jun 3, 2016
Embed
What would you like to do?
Game of life in Elixir (take 1)
# Updated for 1.2.5
defmodule Life do
def run(board) when is_binary(board) do
board |> parse_board |> run
end
def run(board) do
IO.write("\e[H\e[2J")
Life.print_board board
:timer.sleep 250
unless board == next_board(board) do
next_board(board) |> run
end
end
def parse_board(board) do
rows = List.flatten(Regex.scan(~r/^[.o]+$/m, board))
Enum.map rows, &( String.graphemes(&1) )
end
def print_board(board) do
Enum.each board, fn row ->
IO.puts(Enum.join(row))
end
end
def next_board(board) do
board |> Enum.with_index |> Enum.map(fn {row, y} ->
row |> Enum.with_index |> Enum.map(fn {_, x} ->
next_state(board, x, y)
end)
end)
end
def next_state(board, x, y) do
cell = cell_at(board, x, y)
live_count = live_neighbors(board, x, y)
next_state(cell, live_count)
end
def next_state("o", live_count) when live_count in 2..3, do: "o"
def next_state("o", _), do: "."
def next_state(".", live_count) when live_count === 3, do: "o"
def next_state(".", _), do: "."
def cell_at(_, x, y) when (x < 0 or y < 0), do: "."
def cell_at(board, x, y) do
case Enum.at(board, y) do
nil -> "."
row -> Enum.at(row, x, ".")
end
end
def live_neighbors(board, x, y) do
Enum.count(neighbors(board, x, y), &( &1 === "o" ))
end
def neighbors(board, x, y) do
coords = neighbor_coords(x, y)
Enum.map coords, fn [x,y] -> cell_at(board, x,y) end
end
def neighbor_coords(x, y) do
[[x-1, y-1], [x, y-1], [x+1, y-1],
[x-1, y], [x+1, y],
[x-1, y+1], [x, y+1], [x+1, y+1]]
end
end
board = """
.o......
..o.....
ooo.....
........
........
........
........
........
"""
Life.run(board)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment