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