Skip to content

Instantly share code, notes, and snippets.

@leobessa
Created July 7, 2010 14:23
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 leobessa/36ea89b66956fdf3c6cb to your computer and use it in GitHub Desktop.
Save leobessa/36ea89b66956fdf3c6cb to your computer and use it in GitHub Desktop.
class GameOfLife
DEAD = 0
ALIVE = 1
attr_accessor :state
def initialize(size=20)
@size = size
@state = Array.new(@size){ Array.new(@size){ rand 2 } }
end
def evolve
new_state = Array.new(@size){ Array.new(@size) }
@state.each_with_index do |row, x|
row.each_with_index do |cell,y|
new_state[x][y] = case (count_live_neighbours_near(x,y))
when 2
alive?(x,y) ? ALIVE : DEAD
when 3
ALIVE
else
DEAD
end
end
end
@state = new_state
end
def count_live_neighbours_near(x,y)
neighbours_near(x,y).
select{ |a,b| alive?(a,b) }.
length
end
def alive?(x,y)
@state[x%@size][y%@size] == ALIVE
end
def neighbours_near(x,y)
[
[x-1,y-1],[x-1,y],[x-1,y+1],
[ x ,y-1], [x ,y+1],
[x+1,y-1],[x+1,y],[x+1,y+1]
]
end
end
require 'rubygems'
require 'test/unit'
$LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
require 'game_of_life'
class Test::Unit::TestCase
end
require 'rubygems'
require 'sinatra'
require 'haml'
require File.join(File.dirname(__FILE__), 'game_of_life')
get '/game/new' do
@game = GameOfLife.new(28)
haml :index
end
get '/game/evolve' do
@game = GameOfLife.new(28)
@game.state = Array.new(28){ Array.new(28){ 0 } }
params[:state].each_pair do |x,row|
row.each_pair do |y,value|
@game.state[x.to_i][y.to_i] = value.to_i
end
end
@game.evolve
haml :index
end
__END__
@@ layout
%html
%h1 Game of Life
= yield
@@ index
%form.game{:action => "/game/evolve"}
- @game.state.each_with_index do |row, x|
.row
- row.each_with_index do |cell,y|
%input{:type=>"radio", :name => "state[#{x}][#{y}]", :value => 1, :checked => (cell==1)}
%input{:type => "submit", :value => "evolve"}
%script(type="text/javascript"
src="http://code.jquery.com/jquery-latest.js")
:javascript
var refreshId = setInterval(function()
{
$('form.game').submit();
}, 1000);
require 'helper'
class TestGameOfLife < Test::Unit::TestCase
def setup
@game = GameOfLife.new(3)
end
def test_should_kill_with_no_neighbours
@game.state = [[1,0,0],[0,0,0],[0,0,0]]
after = @game.evolve
assert_equal after[0][0], 0
end
def test_should_kill_with_just_one_neighbour
@game.state = [[0,0,0],[1,0,0],[1,0,0]]
after = @game.evolve
assert_equal after[1][0], 0
assert_equal after[2][0], 0
end
def test_should_survive_with_two_neighbours
@game.state = [[0,0,0],[1,1,0],[1,0,0]]
after = @game.evolve
assert_equal after[1][1], 1
end
def test_should_not_give_birth_if_2_neighbours
@game.state = [[0,0,0],[1,0,1],[0,0,0]]
after = @game.evolve
assert_equal after[1][1], 0
end
def test_should_not_give_birth_if_4_neighbours
@game.state = [[0,1,0],[1,0,1],[0,1,0]]
after = @game.evolve
assert_equal after[1][1], 0
end
def test_should_survive_with_three_neighbours
@game.state = [[0,0,0],[1,1,0],[1,1,0]]
after = @game.evolve
assert_equal after[1][1], 1
end
def test_should_kill_with_more_than_3_neighbours
@game.state = [[1,1,1],[1,1,1],[1,1,1]]
after = @game.evolve
assert_equal after, [[0,0,0],[0,0,0],[0,0,0]]
end
def test_should_give_birth_if_3_neighbours
@game.state = [[1,0,0],
[1,1,0],
[0,0,0]]
assert_equal 2,@game.count_live_neighbours_near(1,0)
after = @game.evolve
assert_equal after, [[1,1,1],[1,1,1],[1,1,1]]
end
def test_count_live_neighbours
@game.state = [[0,0,0],
[0,1,0],
[0,0,0]]
assert_equal 1,@game.count_live_neighbours_near(1,0)
assert_equal 0,@game.count_live_neighbours_near(1,1)
@game.state = [[1,0,0],
[1,1,0],
[0,0,0]]
assert_equal 3,@game.count_live_neighbours_near(0,1)
assert_equal 2,@game.count_live_neighbours_near(1,0)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment