Created
September 24, 2012 16:06
-
-
Save benzittlau/3776742 to your computer and use it in GitHub Desktop.
Game of life implementation in ruby
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 World | |
attr_accessor :cells | |
NEXT_STATE = [:dead, :alive, :alive, :dead, :dead, :dead, :dead, :dead] | |
def initialize(cells) | |
@cells = cells | |
end | |
def add_newly_born_cells | |
@cells.each do |cell| | |
(-1..1).each do |x_offset| | |
(-1..1).each do |y_offset| | |
x = cell[:x] + x_offset | |
y = cell[:y] + y_offset | |
if neighbour_count(x,y) == 3 | |
@next_cell_generation.add({:x => x, :y => y}) | |
end | |
end | |
end | |
end | |
end | |
def kill_dying_cells | |
@next_cell_generation.each do |cell| | |
if World::NEXT_STATE[(neighbour_count cell[:x], cell[:y]) - 1] == :dead | |
@next_cell_generation.delete(cell) | |
end | |
end | |
end | |
def evolve | |
@next_cell_generation = @cells.clone | |
kill_dying_cells | |
add_newly_born_cells | |
@cells = @next_cell_generation | |
end | |
def neighbour_count(x, y) | |
get_neighbours(x,y).count | |
end | |
def get_neighbours(x,y) | |
@cells.select {|cell| (cell[:x].between?(x-1, x+1) && cell[:y].between?(y-1, y+1)) && cell != {:x => x, :y => y} } | |
end | |
end |
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
# bowling_spec.rb | |
require './world' | |
describe World, "#evolve" do | |
describe "no live cells" do | |
before(:each) do | |
@world = World.new(Set.new) | |
end | |
it "should return empty world after one turn" do | |
@world.evolve | |
@world.cells.count.should eq(0) | |
end | |
end | |
describe "one live cell" do | |
before(:each) do | |
@world = World.new Set.new([{:x => 0, :y => 0}]) | |
end | |
it "should return empty world after one turn" do | |
@world.evolve | |
@world.cells.count.should eq(0) | |
end | |
end | |
describe "two live cells" do | |
before(:each) do | |
@world = World.new Set.new([{:x => 0, :y => 0}, {:x => 0, :y => 1}]) | |
end | |
it "should return empty world after one turn" do | |
@world.evolve | |
@world.cells.count.should eq(0) | |
end | |
end | |
describe "a block of cells" do | |
before(:each) do | |
@cell_block = Set.new([{:x => 0, :y => 0}, | |
{:x => 0, :y => 1}, | |
{:x => 1, :y => 0}, | |
{:x => 1, :y => 1}]) | |
@world = World.new(@cell_block) | |
end | |
it "should return a matching block of cells" do | |
@world.evolve | |
@cell_block.each do |cell| | |
@world.cells.should include cell | |
end | |
@world.cells.count.should eq @cell_block.count | |
end | |
end | |
describe "five live cells" do | |
before(:each) do | |
# X | |
# XX | |
# XX | |
@cell_block = Set.new([{:x => 0, :y => 0}, | |
{:x => 0, :y => 1}, | |
{:x => 1, :y => 0}, | |
{:x => 1, :y => 1}, | |
{:x => 1, :y => 2}]) | |
@world = World.new(@cell_block) | |
end | |
it "should return five live cells" do | |
# XX | |
# X | |
# XX | |
@world.evolve | |
@world.cells.count.should eq 5 | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment