Last active
December 15, 2015 08:09
-
-
Save burtlo/5228393 to your computer and use it in GitHub Desktop.
Kanye's Game of Life
This file contains hidden or 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 Point < Struct.new(:x,:y) | |
def self.at(x,y) | |
new x, y | |
end | |
def ==(other) | |
other.x == x and other.y == y | |
end | |
def around | |
-1.upto(1).map do |diff_x| | |
-1.upto(1).map do |diff_y| | |
next if diff_x == 0 and diff_y == 0 | |
self.class.at(x + diff_x,y + diff_y) | |
end | |
end.flatten.compact | |
end | |
end | |
class Cell | |
def self.at(x,y) | |
AliveCell.new Point.at(x,y) | |
end | |
def initialize(position) | |
@position = position | |
@neighbors = 0 | |
end | |
attr_reader :position, :neighbors | |
def neighbored | |
@neighbors += 1 | |
end | |
def to_s | |
"#{self.class.name} @ #{position.x},#{position.y} - Neighbors: #{neighbors}" | |
end | |
end | |
class AliveCell < Cell | |
def transform | |
AliveCell.new(position) if neighbors == 2 || neighbors == 3 | |
end | |
end | |
class DeadCell < Cell | |
def transform | |
AliveCell.new(position) if neighbors == 3 | |
end | |
end | |
class Board | |
def initialize(cells=[]) | |
cells.each {|cell| add cell } | |
end | |
def cells | |
@cells ||= Hash.new {|hash,position| hash[position] = DeadCell.new(position)} | |
end | |
def alive_cells | |
cells.values.find_all {|cell| cell.is_a? AliveCell } | |
end | |
def add(cell) | |
cell.position.around.each do |position| | |
found_cell = cells[position] | |
found_cell.neighbored | |
cell.neighbored if found_cell.is_a? AliveCell | |
end | |
cells[cell.position] = cell | |
end | |
def tick | |
surviving_cells = cells.values.map {|cell| cell.transform }.compact | |
self.class.new surviving_cells | |
end | |
end | |
describe Board do | |
describe '#tick' do | |
context "when the board has one lonely cell" do | |
# | |
# X => 0 | |
# | |
it "generates a board with no alive cells" do | |
cell1 = Cell.at 0, 0 | |
board = Board.new | |
board.add cell1 | |
board = board.tick | |
expect(board.alive_cells).to have(0).cells | |
end | |
end | |
context "when the board has two lonely cells" do | |
# | |
# XX => 00 | |
# | |
it "generates a board with no alive cells" do | |
cell1 = Cell.at 0, 0 | |
cell2 = Cell.at 1, 0 | |
board = Board.new | |
board.add cell1 | |
board.add cell2 | |
board = board.tick | |
expect(board.alive_cells).to have(0).cells | |
end | |
end | |
context "when the board has three neighboring cells" do | |
# | |
# X => XX => XX | |
# XX => XX => XX | |
# | |
it "generates the correct board" do | |
cell1 = Cell.at 0, 0 | |
cell2 = Cell.at 1, 0 | |
cell3 = Cell.at 1, 1 | |
board = Board.new | |
board.add cell1 | |
board.add cell2 | |
board.add cell3 | |
board = board.tick | |
expect(board.alive_cells).to have(4).cells | |
board = board.tick | |
# Four cells next to each other are in perfect harmony | |
expect(board.alive_cells).to have(4).cells | |
end | |
end | |
context "when a board has five live cells" do | |
# | |
# X => XXX => XXX => XXX | |
# XXX => X0X => X0X => X0X | |
# X => XXX => XXX => XXX | |
# | |
it "generates the correct board" do | |
cell1 = Cell.at 0, 0 | |
cell2 = Cell.at 1, 0 | |
cell3 = Cell.at 0, 1 | |
cell4 = Cell.at -1,0 | |
cell5 = Cell.at 0,-1 | |
board = Board.new | |
board.add cell1 | |
board.add cell2 | |
board.add cell3 | |
board.add cell4 | |
board.add cell5 | |
board = board.tick | |
expect(board.alive_cells).to have(8).cells | |
board = board.tick | |
expect(board.alive_cells).to have(8).cells | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
cells.values.grep(AliveCell)