Created
April 4, 2014 21:56
-
-
Save bendyorke/9983865 to your computer and use it in GitHub Desktop.
This file contains 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
module GameOfLife | |
def self.play input, n | |
# return 42 if input == "the universe and everything" | |
@board = make_board_from input | |
n.times { age!; print_board; sleep(0.2) } | |
end | |
def self.age! | |
results = parse_cells | |
process results | |
end | |
def self.parse_cells | |
deep_map do |x,y,cell| | |
colony = get_block_at(y,x).select(&:alive?).count | |
colony -= 1 if cell.alive? | |
[:kill!,:kill!,nil,:grow!].fetch(colony, :kill!) | |
end | |
end | |
def self.process results | |
deep_map(results) { |x,y,action| @board[y][x].send(action) if action } | |
end | |
def self.deep_map grid = @board | |
grid.map.with_index do |row, y| | |
row.map.with_index do |val, x| | |
yield(x,y,val,row) | |
end | |
end | |
end | |
def self.get_block_at y, x | |
lower_y = y-1 < 0 ? y : y-1 | |
lower_x = x-1 < 0 ? x : x-1 | |
@board[lower_y..y+1].map { |row| row[lower_x..x+1] }.flatten | |
end | |
def self.make_board_from input | |
input.map do |row| | |
row.split('').map { |point| Cell.new point.to_i } | |
end | |
end | |
def self.print_board | |
print "\e[2J" | |
print "\e[H" | |
@board.each { |row| puts row.join } | |
end | |
Cell = Struct.new :status do | |
def alive? | |
self.status == 1 | |
end | |
def grow! | |
self.status = 1 | |
end | |
def kill! | |
self.status = 0 | |
end | |
def to_s | |
self.alive? ? "*" : "-" | |
end | |
end | |
end | |
GameOfLife::play(ARGV[0..-2], ARGV[-1].to_i) if __FILE__ == $0 |
This file contains 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
require_relative 'game_of_life' | |
describe GameOfLife do | |
describe '#make_board_from' do | |
it 'makes a properly sized array' do | |
GameOfLife::make_board_from(%w[10 10]).map(&:length).should eq [2,2] | |
end | |
it 'makes a Cell Struct for each input' do | |
GameOfLife::make_board_from(%w[10 10])[0][0].class.should eq GameOfLife::Cell | |
end | |
end | |
describe '#age!' do | |
it 'processes all the inputs before aging' do | |
GameOfLife.instance_variable_set :@board, Array.new(3) { Array.new(3) { GameOfLife::Cell.new(1) } } | |
GameOfLife::age! | |
GameOfLife.instance_variable_get(:@board).should eq GameOfLife::make_board_from %w[101 000 101] | |
end | |
it 'freezes "boat"' do | |
GameOfLife.instance_variable_set :@board, GameOfLife::make_board_from(%w[00000 01100 01010 00100 00000]) | |
GameOfLife::age! | |
GameOfLife.instance_variable_get(:@board).should eq GameOfLife::make_board_from %w[00000 01100 01010 00100 00000] | |
end | |
it 'pulses "toad" (level 2)' do | |
GameOfLife.instance_variable_set :@board, GameOfLife::make_board_from(%w[000000 000000 001110 011100 000000 000000]) | |
GameOfLife::age! | |
GameOfLife.instance_variable_get(:@board).should eq GameOfLife::make_board_from %w[000000 000100 010010 010010 001000 000000] | |
end | |
it 'pulses "pulsar" (level 3)' do | |
GameOfLife.instance_variable_set :@board, GameOfLife::make_board_from(%w[000000000000000 000111000111000 000000000000000 | |
010000101000010 010000101000010 010000101000010 | |
000111000111000 000000000000000 000111000111000 | |
010000101000010 010000101000010 010000101000010 | |
000000000000000 000111000111000 000000000000000]) | |
2.times { GameOfLife::age! } | |
GameOfLife.instance_variable_get(:@board).should eq GameOfLife::make_board_from %w[000000000000000 000110000011000 000011000110000 | |
010010101010010 011101101101110 001010101010100 | |
000111000111000 000000000000000 000111000111000 | |
001010101010100 011101101101110 010010101010010 | |
000011000110000 000110000011000 000000000000000] | |
end | |
end | |
describe GameOfLife::Cell do | |
it 'tests that cell is alive' do | |
GameOfLife::Cell.new(1).alive?.should eq true | |
GameOfLife::Cell.new(0).alive?.should eq false | |
end | |
it 'can grow and kill cells' do | |
cell = GameOfLife::Cell.new(0) | |
cell.grow! | |
cell.alive?.should eq true | |
cell.kill! | |
cell.alive?.should eq false | |
end | |
it 'prints based on its status' do | |
GameOfLife::Cell.new(0).to_s.should eq '-' | |
GameOfLife::Cell.new(1).to_s.should eq '*' | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment