Created
September 1, 2015 15:45
-
-
Save anonymous/894097cbb3ab324896ca 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
ALIVE = "*" | |
DEAD = " " | |
INTERVAL = 0.05 | |
HEIGHT, WIDTH = `stty size`.split.map &:to_i | |
Signal.trap(:INT){ puts; exit 0 } | |
class Lifegame | |
def initialize(height = HEIGHT, width = WIDTH, alive = ALIVE, dead = DEAD) | |
set_size height, width | |
@alive = alive | |
@dead = dead | |
@turn = 0 | |
end | |
def set_size(height, width) | |
@height = height | |
@width = width | |
reset | |
end | |
def reset | |
@field = Array.new(@height){ Array.new(@width){ rand(2) == 1 } } | |
end | |
def draw | |
@field.map{|row| row.map{|cell| cell ? @alive : @dead }.join } * "\n" | |
end | |
def get_cell(row, col) | |
@field[row][col] | |
end | |
def get_neighbors(row, col) | |
(-1..1).map do |i| | |
r = row + i | |
r -= @height if r >= @height | |
(-1..1).map do |j| | |
c = col + j | |
c -= @width if c >= @width | |
@field[r][c] | |
end | |
end | |
end | |
def count_neighbors(cell, row, col) | |
neighbors = get_neighbors row, col | |
neighbors.flatten.count(true) + (cell ? -1 : 0) | |
end | |
def next_status(row, col) | |
cell = get_cell row, col | |
neighbors = count_neighbors cell, row, col | |
judge cell, neighbors | |
end | |
def judge(cell, neighbors) | |
# セルが生存している時 => 周囲の生存セルが2つ or 3つだったら生存し続ける | |
# セルが死んでいる時 => 周囲の生存セルがちょうど3つだったら生まれる | |
# それ以外なら死ぬ | |
cell ? neighbors.between?(2, 3) : neighbors == 3 | |
end | |
def advance #ターンを進める | |
@turn += 1 | |
@field = Array.new(@height){|row| Array.new(@width){|col| next_status row, col } } | |
end | |
def active_cells | |
@field.flatten.count true | |
end | |
def run(interval = INTERVAL) | |
puts "\e[2J" #画面消去 | |
loop do | |
start = Time.now.to_f #更新開始 | |
print "\e[1;1H" #1行目の1列目にカーソル移動 | |
print draw #フィールドを出力 | |
print "\e[#{@height};1H" #一番下の行にカーソル移動 | |
print "%5d turn, %5d cells alive. " % [@turn, active_cells] #ステータス行を出力 | |
print "\e[#{@height};#{@width}H" #右下にカーソル移動 (やったほうが美しい) | |
advance #状態を更新 | |
stop = Time.now.to_f #更新終了 | |
elapsed = stop - start #作業にかかった時間 | |
#スリープ (画面が大きいと割とモッサリするから作業時間はインターバルからマイナスする) | |
sleep interval < elapsed ? 0 : interval - elapsed | |
end | |
end | |
end | |
Lifegame.new.run |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment