Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement