Skip to content

Instantly share code, notes, and snippets.

@avdi avdi/gol.exs
Last active Jun 3, 2016

Embed
What would you like to do?
Game of life in Elixir (take 1)
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 1000
board = next_board(board)
run(board)
end
def parse_board(board) do
rows = 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
Enum.map board, fn row, y ->
Enum.map row, 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)
@avdi

This comment has been minimized.

Copy link
Owner Author

commented Jul 10, 2013

Obviously this version just targets the most basic stuff like functions and pattern matching, there's no process-wrangling here.

@philss

This comment has been minimized.

Copy link

commented Jul 17, 2013

@avdi I get an error when running with "Elixir 0.9.4dev". I notice that a comma is missing at line 45:

def next_state(".", _), do: "."
@javichito

This comment has been minimized.

Copy link

commented Aug 3, 2013

same here

@billgathen

This comment has been minimized.

Copy link

commented Aug 19, 2014

Requires a few minor tweaks to run under Elixir 0.15.1 (including the missing comma). I'm just learning Elixir and really enjoyed debugging this. 😄

15,16c15,16
<     rows = Regex.scan(%r/^[.o]+$/m, board)
<     Enum.map rows, String.graphemes(&1)

---
>     rows = Regex.scan(~r/^[.o]+$/m, board)
>     Enum.map rows, &String.graphemes(List.first(&1))
26,27c26,27
<     Enum.map board, fn row, y ->
<       Enum.map row, fn _, x ->

---
>     Enum.map Enum.with_index(board), fn { row, y } ->
>       Enum.map Enum.with_index(row), fn { _, x } ->
45c45
<   def next_state(".", _) do: "."

---
>   def next_state(".", _), do: "."
57c57
<     Enum.count(neighbors(board, x, y), &1 === "o")

---
>     Enum.count(neighbors(board, x, y), &(&1 === "o"))

Forked here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.