Skip to content

Instantly share code, notes, and snippets.

@rob-brown
Last active August 29, 2015 14:09
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rob-brown/6969b31f0417dcd17ed1 to your computer and use it in GitHub Desktop.
Save rob-brown/6969b31f0417dcd17ed1 to your computer and use it in GitHub Desktop.
Conway's Game of Life
defmodule Life do
# Defaults to B3/S23
defstruct cells: [[]], born: [3], stays: [2, 3], width: 10, height: 10, step: 0
def run(file) do
file |> read_file |> loop
end
def loop(life) do
life |> print |> wait |> step |> loop
end
## Helpers
defp read_file(file) do
lines = File.stream! file
height = Enum.count lines
width = lines |> Enum.max_by(&String.length/1) |> String.length
cells = Enum.map lines, &(parse_line &1, width)
%Life{cells: cells, width: width, height: height}
end
defp parse_line(line, width) do
for x <- 1..width do
case String.at(line, x - 1) do
"#" -> 1
" " -> 0
_ -> 0
end
end
end
defp wait(life) do
:timer.sleep 250
life
end
defp step(life) do
cells = for row <- 1..life.height do
for column <- 1..life.width do
next_value life, row - 1, column - 1
end
end
%Life{life | cells: cells, step: life.step + 1}
end
defp next_value(life, row, column) do
cell = at(life, row, column)
count = count_adjacent_life life, row, column
_next_value life, cell, count
end
defp _next_value(life, 0, count), do: count in life.born && 1 || 0
defp _next_value(life, 1, count), do: count in life.stays && 1 || 0
defp count_adjacent_life(life, row, column) do
for x <- [-1, 0, 1], y <- [-1, 0, 1], {x,y} != {0,0} do
at(life, row + x, column + y)
end
|> Enum.sum
end
defp at(life, row, column) when row < 0 or column < 0, do: 0
defp at(life, row, column), do: ((life.cells |> Enum.at(row) || []) |> Enum.at(column) || 0)
defp print(life) do
divider = for _ <- 1..life.width + 2, into: "", do: "="
IO.puts "#{divider} (#{life.step})"
for line <- life.cells do
for cell <- line, into: "" do
case cell do
1 -> "#"
0 -> " "
end
end
|> IO.puts
end
life
end
end
# #
# #
## ##
### ## ## ###
# # # # # #
## ##
## ##
# # # # # #
### ## ## ###
## ##
# #
# #
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment