Last active
August 29, 2015 13:57
-
-
Save geofflane/9634164 to your computer and use it in GitHub Desktop.
Practice Game Of Life
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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