Skip to content

Instantly share code, notes, and snippets.

@marksim
Created December 15, 2013 06:13
Show Gist options
  • Select an option

  • Save marksim/7969574 to your computer and use it in GitHub Desktop.

Select an option

Save marksim/7969574 to your computer and use it in GitHub Desktop.

Revisions

  1. marksim created this gist Dec 15, 2013.
    75 changes: 75 additions & 0 deletions game_of_life.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,75 @@
    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