Skip to content

Instantly share code, notes, and snippets.

@kirikiriyamama
Last active June 22, 2016 06:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kirikiriyamama/b51a1ba6564616792eaa to your computer and use it in GitHub Desktop.
Save kirikiriyamama/b51a1ba6564616792eaa to your computer and use it in GitHub Desktop.
class GameOfLife
def initialize
@field = Field.new
end
def run(fps:)
loop do
puts "\e[0;0H\e[2J#{@field}"
sleep 1.0 / fps
step
end
end
def step
prev_field = Marshal.load(Marshal.dump(@field))
Field::X_RANGE.to_a.product(Field::Y_RANGE.to_a).each do |x, y|
count = prev_field.neighbours_at(x, y).count(&:alive?)
prev_cell = prev_field.at(x, y)
next_cell = @field.at(x, y)
case
when prev_cell.alive? && (2..3).cover?(count)
next_cell.live!
when prev_cell.dead? && count == 3
next_cell.live!
else
next_cell.die!
end
end
end
class Field
WIDTH = 50
HEIGHT = 50
X_RANGE = 0...WIDTH
Y_RANGE = 0...HEIGHT
def initialize
@map = Array.new(HEIGHT).collect{ Array.new(WIDTH).collect{ Cell.new } }
end
def at(x, y)
(X_RANGE.cover?(x) && Y_RANGE.cover?(y)) ? @map[y][x] : nil
end
def neighbours_at(x, y)
[
at(x - 1, y - 1), at(x, y - 1), at(x + 1, y - 1),
at(x - 1, y ), at(x + 1, y ),
at(x - 1, y + 1), at(x, y + 1), at(x + 1, y + 1)
].compact
end
def to_s
@map.collect{ |line| "|#{line.collect(&:to_s).join('|')}|" }.join("\n")
end
end
class Cell
def initialize
@alive = [true, false].sample
end
def live!
@alive = true
end
def die!
@alive = false
end
def alive?
@alive
end
def dead?
!@alive
end
def to_s
alive? ? '@' : '_'
end
end
end
GameOfLife.new.run(fps: 60)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment