Created
February 17, 2014 01:03
-
-
Save benneuman/9042966 to your computer and use it in GitHub Desktop.
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
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