Skip to content

Instantly share code, notes, and snippets.

@geofflane
Last active August 29, 2015 13:57
Show Gist options
  • Save geofflane/9634164 to your computer and use it in GitHub Desktop.
Save geofflane/9634164 to your computer and use it in GitHub Desktop.
Practice Game Of Life
class Cell
DEAD = '.'
ALIVE = 'x'
attr_accessor :value
def self.create(val, position)
if val == DEAD
DeadCell.new(position)
else
LiveCell.new(position)
end
end
def evolve_at(board)
alive_neighbors = count_alive(board.neighbor_cells(@position))
evolve(alive_neighbors)
end
def alive?
value == ALIVE
end
def dead?
! alive?
end
private
def count_alive(cells)
cells.compact.count(&:alive?)
end
class LiveCell < Cell
def initialize(pos)
@position = pos
end
def value
Cell::ALIVE
end
def evolve(alive_neighbors)
if alive_neighbors < 2 || alive_neighbors > 3
DeadCell.new(@position)
else
self
end
end
end
class DeadCell < Cell
def initialize(pos)
@position = pos
end
def value
Cell::DEAD
end
def evolve(alive_neighbors)
if alive_neighbors == 3
LiveCell.new(@position)
else
self
end
end
end
end
require_relative 'cell'
class GameOfLife
def self.start(board)
width = board[0].size
cells = board.flatten.each_with_index.map { |c, i| Cell.create(c, i) }
GameOfLife.new(cells, width)
end
def initialize(cells, width)
@cells = cells
@width = width
end
def board
@cells.map(&:value).each_slice(@width).to_a
end
def center_cell
@cells[@cells.size / 2]
end
def evolve
new_board = @cells.map { |current| current.evolve_at(self) }
GameOfLife.new(new_board, @width)
end
def neighbor_cells(i)
neighbors(i).map { |n| @cells[n] }
end
private
def neighbors(x)
# NOTE: I don't actually think this is correct
[x - @width - 1, x - @width, x - @width + 1, x - 1, x + 1, x + @width - 1, x + @width, x + @width + 1]
end
end
Given(/^the following setup$/) do |table|
@game = GameOfLife.start(table.raw)
end
When(/^I evolve the board$/) do
@game = @game.evolve
end
Then(/^the center cell should be dead$/) do
expect(@game.center_cell).to be_dead
end
Then(/^the center cell should be alive$/) do
expect(@game.center_cell).to be_alive
end
Then(/^I should see the following board$/) do |table|
@expected_board = table.raw
expect(@game.board).to eq(@expected_board)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment