Skip to content

Instantly share code, notes, and snippets.

@haru01
Created June 10, 2012 23:43
Show Gist options
  • Save haru01/2907741 to your computer and use it in GitHub Desktop.
Save haru01/2907741 to your computer and use it in GitHub Desktop.
lifegame
# encoding: utf-8
describe "LifeGame" do
ALIVE = 1
DEAD = 0
subject { Space.new(seed).next_time.status(1,1) }
context "誕生:死んでいるセルに隣接する生きたセルがちょうど3つあれば次世代が誕生する" do
let(:seed) {[ [1,1,0],
[1,0,0],
[0,0,0]]}
it { should == ALIVE }
end
context "生存:生きているセルに隣接する生きたセルが2つならば、次の世代でも生存する。" do
let(:seed) {[ [1,1,0],
[0,1,0],
[0,0,0]]}
it { should == ALIVE }
end
context "生存:生きているセルに隣接する生きたセルが3つならば、次の世代でも生存する。" do
let(:seed) {[ [1,1,1],
[0,1,0],
[0,0,0]]}
it { should == ALIVE }
end
context "過疎:生きているセルに隣接する生きたセルが1つ以下ならば、過疎により死滅する。" do
let(:seed) {[ [0,0,0],
[0,1,1],
[0,0,0]]}
it { should == DEAD }
end
context "過密:生きているセルに隣接する生きたセルが4つ以上ならば、過密により死滅する。" do
let(:seed) {[ [1,1,1],
[1,1,0],
[0,0,0]]}
it { should == DEAD }
end
end
describe "cell#count_alive_around" do
let(:init) {[ [1,1,1,1],
[1,1,0,1],
[1,0,0,1],
[0,0,1,1]]}
context "8周辺がある場合の隣接する生きている要素が取得できること" do
subject { Space.new(init).cells[2][2].count_alive_around }
it { should == 5 }
end
context "左上隅の場合の隣接する生きている要素が取得できること" do
subject { Space.new(init).cells[0][0].count_alive_around }
it { should == 3 }
end
context "上辺の場合の隣接する生きている要素が取得できること" do
subject { Space.new(init).cells[0][1].count_alive_around }
it { should == 4 }
end
context "右上の場合の隣接する生きている要素が取得できること" do
subject { Space.new(init).cells[0][3].count_alive_around }
it { should == 2 }
end
context "左下の場合の隣接する生きている要素が取得できること" do
subject { Space.new(init).cells[3][0].count_alive_around }
it { should == 1 }
end
context "右下の場合の隣接する生きている要素が取得できること" do
subject { Space.new(init).cells[3][3].count_alive_around }
it { should == 2 }
end
context "右下の場合の隣接する生きている要素が取得できること" do
subject { Space.new(init).cells[3][3].count_alive_around }
it { should == 2 }
end
end
class Space
ALIVE = 1
DEAD = 0
attr_accessor :cells
def initialize(seeds=[])
@cells = []
seeds.each_with_index do |rows, row_i|
@cells[row_i] = []
rows.each_with_index do |status, col_i|
@cells[row_i] << Cell.new(status, row_i, col_i, @cells)
end
end
end
class Cell
attr_accessor :status, :cells, :row, :col
def initialize(status, row, col, cells)
@status, @row, @col, @cells = status, row, col, cells
end
def next_time_status
# 誕生
if dead? and count_alive_around == 3
return ALIVE
# 生存(維持)
elsif alive? and (count_alive_around == 2 or count_alive_around == 3)
return ALIVE
end
# 過疎、過密
DEAD
end
def count_alive_around
cells.flatten.select { |cell|
around?(cell) and
cell.alive?
}.size
end
def around?(other_cell)
other_cell != self and
(row - 1 <= other_cell.row and other_cell.row <= row + 1 and
col - 1 <= other_cell.col and other_cell.col <= col + 1)
end
def dead?
status == 0
end
def alive?
not dead?
end
def to_s
"#{status}<-[#{row}][#{col}]"
end
end
def next_time
next_status_a = []
cells.each_with_index do |rows, row_i|
next_status_a[row_i] = []
rows.each_with_index do |cell, col_i|
next_status_a[row_i] << cells[row_i][col_i].next_time_status
end
end
Space.new(next_status_a)
end
def status(row, col)
@cells[row][col].status
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment