Skip to content

Instantly share code, notes, and snippets.

@benneuman
Created February 17, 2014 01:03
Show Gist options
  • Save benneuman/9042966 to your computer and use it in GitHub Desktop.
Save benneuman/9042966 to your computer and use it in GitHub Desktop.
require 'rspec'
class Board
LIVE = "X"
DEAD = "O"
attr_reader :board
def initialize(board_array)
@board = parse_in(board_array)
@point_finder = PointFinder.new(@board)
end
def evolve
take_neighbor_count
@board.flatten.each { |point| point.evolve }
end
def take_neighbor_count
@board.flatten.each { |point| point.count_neighbors }
end
def parse_in(board_array)
board_array.map.with_index do |row, row_index|
row.map.with_index do |point, col_index|
has_cell = (point == "X")
Spot.new([row_index, col_index], self, has_cell)
end
end
end
def parse
@board.map do |row|
row.map { |point| (point.has_cell?) ? "X" : "O"}
end
end
def find_point(index)
@point_finder.find_point(index)
end
end
class PointFinder
def initialize(board)
@board = board
end
def find_point(index)
row_index, col_index = index
return nil if row_index < 0 || col_index < 0
row = @board[row_index]
return nil if row.nil?
row[col_index]
end
end
class NeighborFinder
def initialize(point, board)
@point = point
@board = board
end
def get_neighbors
get_neighbor_indexes(@point.index).collect { |index| find_point(index)}.reject(&:nil?)
end
def get_neighbor_indexes(index)
row_index, col_index = index
neighbor_indexes = [
[row_index, col_index - 1],
[row_index, col_index + 1],
[row_index - 1, col_index],
[row_index + 1, col_index],
[row_index - 1, col_index - 1],
[row_index - 1, col_index + 1],
[row_index + 1, col_index - 1],
[row_index + 1, col_index + 1]
]
end
def find_point(index)
@board.find_point(index)
end
end
class Spot
attr_accessor :has_cell, :neighbor_count, :index
def initialize(index, board, has_cell = false)
@index = index
@board = board
@has_cell = has_cell
@neighbor_finder = NeighborFinder.new(self, @board)
end
def board
@board.board
end
def has_cell?
@has_cell
end
def evolve
if has_cell?
@has_cell = (neighbor_count == 2 || neighbor_count == 3)
else
@has_cell = (neighbor_count == 3)
end
end
def count_neighbors
@neighbor_count = get_neighbors.count(&:has_cell?)
end
def get_neighbors
@neighbor_finder.get_neighbors
end
end
describe "A dead cell" do
context "with no neighbors" do
it "should stay dead" do
board = Board.new([%w(O)])
board.evolve
board.parse.should == [%w(O)]
end
end
end
describe "A live cell" do
# Bad test because doe#s not fail
context "with no neighbors" do
it "should die" do
board = Board.new([%w(X)])
board.evolve
board.parse.should == [%w(O)]
end
end
context "with one neighbor" do
it "should die" do
board = Board.new([%w(O X)])
board.evolve
board.parse.should == [%w(O O)]
end
end
context "with two neighbors" do
it "should live" do
board = Board.new([%w(X X X)])
board.evolve
board.parse.should == [%w(O X O)]
end
end
context "with three neighbors" do
it "should live" do
board = Board.new([%w(X X), %w(X X)])
board.evolve
board.parse.should == [%w(X X), %w(X X)]
end
end
context "with more than three neighbors" do
it "should die" do
board = Board.new([%w(X O O), %w(X X X), %w(X O X)])
board.evolve
board.parse.should == [%w(X O O), %w(X O X), %w(X O X)]
end
end
end
describe "A dead cell" do
context "with exactly three neighbors" do
it "should come alive" do
board = Board.new([%w(X X), %w(X O)])
board.evolve
board.parse.should == [%w(X X), %w(X X)]
end
end
end
#X O X -> #X O X -> #O O O
#X X X #X O X #X O X
#O X O #X X X #X O X
describe "An evolved board" do
context "should continue evolving by the rules" do
start = [%w(X O X), %w(X X X), %w(O X O)]
first_evolution = [%w(X O X), %w(X O X), %w(X X X)]
second_evolution = [%w(O O O), %w(X O X), %w(X O X)]
it "the first evolution should follow the rules" do
board = Board.new(start)
expect {board.evolve}.to change {board.parse}.from(start).to(first_evolution)
end
it "the second evolution should still follow the rules" do
board = Board.new(start)
board.evolve
expect {board.evolve}.to change {board.parse}.from(first_evolution).to(second_evolution)
end
end
end
# #Testing live cell with no neighbors dies
# board = [%w(X)]
# assert(evolve(board), [%w(O)])
# #Testing live cell with one neighbor dies
# board = [%w(O X)]
# assert(evolve(board), [%w(O O)])
# #Testing live cell with two neighbors stays alive
# board = [%w(X X X)]
# assert(evolve(board), [%w(O X O)])
# #Testing live cell with three neighbors stays alive
# board = [%w(X X), %w(X X)]
# assert(evolve(board), [%w(X X), %w(X X)])
# #Testing live cell with more than three neighbors dies
# # X O O
# # X X X
# # X O X
# board = [%w(X O O), %w(X X X), %w(X O X)]
# assert(evolve(board), [%w(X O O), %w(X O X), %w(X O X)])
# #Testing dead cell with exactly three live neighbors comes alive
# # X X
# # X O
# board = [%w(X X), %w(X O)]
# assert(evolve(board), [%w(X X), %w(X X)])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment