Skip to content

Instantly share code, notes, and snippets.

@timuruski
Created June 21, 2014 21:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timuruski/dcdc2c50077735bcf08a to your computer and use it in GitHub Desktop.
Save timuruski/dcdc2c50077735bcf08a to your computer and use it in GitHub Desktop.
class World
def initialize(cells)
@cells = cells
@row_count = cells.length
@col_count = cells[0].length
end
def living_neighbours(col, row)
[
cell(col, row - 1), # NORTH
cell(col + 1, row - 1), # NORTH-EAST
cell(col + 1, row), # EAST
cell(col + 1, row + 1), # SOUTH-EAST
cell(col, row + 1), # SOUTH
cell(col - 1, row + 1), # SOUTH-WEST
cell(col - 1, row), # WEST
cell(col - 1, row - 1) # NORTH-WEST
].select(&:living?)
end
def cell(col,row)
@cells[row % @row_count][col % @col_count]
end
def next
new_cells = cell_map { |c|
c.next(living_neighbours(c))
}
self.class.new(@cells)
end
def cell_map
@cells.map { |row|
row.map { |cell|
yield cell
}
}
end
end
class Cell
def self.next(target, neighbours)
living_neighbours = neighbours.count { |c| c.living? }
if target.living?
next_living = living_neighbours > 1 && living_neighbours < 4
else
next_living = living_neighbours == 3
end
new(living: next_living)
end
def initialize(living: false)
@living = living
end
def living?
@living
end
end
describe "Conway's Game of Life" do
def alive
Cell.new(living: true)
end
def dead
Cell.new(living: false)
end
describe "Cell.new" do
it "is not living by default" do
expect(Cell.new.living?).to be false
end
it "can be living" do
expect(Cell.new(living: true).living?).to be true
end
it "can be not living" do
expect(Cell.new(living: false).living?).to be false
end
end
describe "Cell.next" do
context "with a living target cell" do
let(:target) { Cell.new(living: true) }
context "and 1 living neighbour" do
it "produces an dead cell" do
neighbours = [
dead,
alive,
dead
]
expect(Cell.next(target, neighbours).living?).to be false
end
end
context "and 2 living neighbours" do
it "produces a living cell" do
neighbours = [
alive,
alive,
dead
]
expect(Cell.next(target, neighbours).living?).to be true
end
end
context "and 3 living neighbours" do
it "produces a living cell" do
neighbours = [
alive,
alive,
alive
]
expect(Cell.next(target, neighbours).living?).to be true
end
end
context "and 4 living neighbours" do
it "produces an dead cell" do
neighbours = [
alive,
alive,
alive,
alive
]
expect(Cell.next(target, neighbours).living?).to be false
end
end
end
context "with an dead target cell" do
let(:target) { Cell.new(living: false) }
context "and 2 living neighbours" do
it "produces an dead cell" do
neighbours = [
alive,
alive,
dead
]
expect(Cell.next(target, neighbours).living?).to be false
end
end
context "and 3 living neighbours" do
it "produces an living cell" do
neighbours = [
alive,
alive,
alive
]
expect(Cell.next(target, neighbours).living?).to be true
end
end
context "and 4 living neighbours" do
it "produces an dead cell" do
neighbours = [
alive,
alive,
alive,
alive
]
expect(Cell.next(target, neighbours).living?).to be false
end
end
end
end
describe World do
describe "#neighbours" do
it "returns an empty array if no living neighbours" do
a,b,c = dead, dead, dead
d,e,f = dead, dead, dead
g,h,i = dead, dead, dead
subject = World.new([[a,b,c],
[d,e,f],
[g,h,i]])
expect(subject.living_neighbours(1,1)).to eq([])
end
it "returns an array of only the living neighbours" do
a,b,c = alive, alive, alive
d,e,f = alive, dead, alive
g,h,i = alive, alive, alive
subject = World.new([[a,b,c],
[d,e,f],
[g,h,i]])
expect(subject.living_neighbours(1,1)).to match_array([a,b,c,d,f,g,h,i])
end
it "returns an array without the dead neighbours" do
a,b,c = dead, alive, dead
d,e,f = alive, dead, alive
g,h,i = dead, alive, dead
subject = World.new([[a,b,c],
[d,e,f],
[g,h,i]])
expect(subject.living_neighbours(1,1)).to match_array([b,d,f,h])
end
it "returns an array without the dead neighbours" do
a,b,c,d,e = alive, alive, alive, alive, alive
f,g,h,i,j = alive, alive, alive, alive, alive
k,l,m,n,o = alive, alive, alive, alive, alive
p,q,r,s,t = alive, alive, alive, alive, alive
u,v,w,x,y = alive, alive, alive, alive, alive
subject = World.new([[a,b,c,d,e],
[f,g,h,i,j],
[k,l,m,n,o],
[p,q,r,s,t],
[u,v,w,x,y]])
expect(subject.living_neighbours(2,2)).to match_array([g,h,i,l,n,q,r,s])
end
it "returns neighbours wrapping around the world" do
a,b,c = alive, alive, alive
d,e,f = alive, alive, alive
g,h,i = alive, alive, alive
subject = World.new([[a,b,c],
[d,e,f],
[g,h,i]])
expect(subject.living_neighbours(2,2)).to match_array([a,b,c,d,e,f,g,h])
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment