Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
require 'rspec'
class GameOfLife
def initialize(generation)
@generation = generation
end
attr_reader :generation
def is_alive?(x, y)
generation.include?([x, y])
end
def number_of_neighbors_for(x, y)
generation.select do |dx, dy|
(x-1..x+1).include?(dx) && (y-1..y+1).include?(dy)
end.count - (is_alive?(x, y) ? 1 : 0)
end
def should_regen?(x, y)
!generation.include?([x, y]) && number_of_neighbors_for(x, y) == 3
end
def regenerate_dead_neighbors(x, y)
(-4..4).map { |m| [x+m/3, y+m%3] if should_regen?(x+m/3, y+m%3) }.compact
end
def should_survive?(x, y)
[2, 3].include?(number_of_neighbors_for(x, y))
end
def tick
@generation = generation.map do |x, y|
regenerate_dead_neighbors(x, y) + (should_survive?(x, y) ? [[x, y]] : [])
end.flatten(1).uniq.sort
end
end
describe "Game of Life!!!" do
let(:game) { GameOfLife.new(board) }
context "Lonely" do
let(:board) { [[1, 1]] }
it "dies after one generation" do
game.tick
expect(game.generation).to be_empty
end
end
context "Continuing" do
let(:board) { [[0, 0], [0, 1], [1, 0], [1, 1], [2, 2], [2, 3], [3, 2], [3, 3]] } # Beacon
it "knows how many neighbors" do
expect(game.number_of_neighbors_for(1, 1)).to eql 4
end
it "2 die after one generation" do
game.tick
expect(game.generation).to eql [[0, 0], [0, 1], [1, 0], [2, 3], [3, 2], [3, 3]]
end
end
context "Regenerate" do
let(:board) { [[0, 0], [0, 1], [1, 0], [2, 3], [3, 2], [3, 3]] }
it "knows how many neighbors" do
expect(game.number_of_neighbors_for(1, 1)).to eql 3
end
it "regenerates after one generation with exactly 3 neighbors" do
game.tick
expect(game.generation).to eql [[0, 0], [0, 1], [1, 0], [1, 1], [2, 2], [2, 3], [3, 2], [3, 3]].sort
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment