Skip to content

Instantly share code, notes, and snippets.

@terotil
Created August 17, 2011 23:35
Show Gist options
  • Save terotil/1152923 to your computer and use it in GitHub Desktop.
Save terotil/1152923 to your computer and use it in GitHub Desktop.
Conway's Game of Life
#!/usr/bin/ruby
seed = <<eos
..........
..........
..#.......
...#......
...##.....
...##.....
....#.....
.....#....
......#...
..........
eos
class Matrix
def initialize(matrix)
@m = matrix
end
def self.from_seed(seed)
Matrix.new(seed.strip.split("\n").map { |row| row.split '' })
end
def next
(0...rows).map do |y|
(0...cols).map do |x|
type_after_tick(x, y)
end
end.to_matrix
end
def type_after_tick(x, y)
count = count_alive(x, y)
return '#' if count == 4 && self[x, y].alive?
count == 3 ? '#' : '.'
end
# count of alive cells in 3x3 matrix around given center
def count_alive(cx, cy)
(cx-1..cx+1).map do |x|
(cy-1..cy+1).map do |y|
self[x, y].alive? ? 1 : 0
end
end.flatten.reduce(:+)
end
def [](x, y)
# wrap to torus surface using modulo arithmetics and the fact that
# a[-n] == a[a.length-n]
@m[y%10][x%10]
end
def rows
@m.count
end
def cols
@m.first.count
end
def to_s
@m.map(&:join).join "\n"
end
end
class String
def alive?
self == '#'
end
end
class Array
def to_matrix
Matrix.new self
end
end
Signal.trap 'INT' do
clear_and_home
exit
end
def clear_and_home
puts "\e[1J" # clear terminal up to cursor position
puts "\e[H" # move cursor to upper left corner
end
matrix = Matrix.from_seed(seed)
while true
clear_and_home
puts matrix.to_s
matrix = matrix.next
sleep 0.1
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment