Advertisement
Guest User

Untitled

a guest
Sep 1st, 2015
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.47 KB | None | 0 0
  1. ALIVE = "*"
  2. DEAD = " "
  3.  
  4. INTERVAL = 0.05
  5. HEIGHT, WIDTH = `stty size`.split.map &:to_i
  6.  
  7. Signal.trap(:INT){ puts; exit 0 }
  8.  
  9. class Lifegame
  10. def initialize(height = HEIGHT, width = WIDTH, alive = ALIVE, dead = DEAD)
  11. set_size height, width
  12. @alive = alive
  13. @dead = dead
  14. @turn = 0
  15. end
  16.  
  17. def set_size(height, width)
  18. @height = height
  19. @width = width
  20. reset
  21. end
  22.  
  23. def reset
  24. @field = Array.new(@height){ Array.new(@width){ rand(2) == 1 } }
  25. end
  26.  
  27. def draw
  28. @field.map{|row| row.map{|cell| cell ? @alive : @dead }.join } * "\n"
  29. end
  30.  
  31. def get_cell(row, col)
  32. @field[row][col]
  33. end
  34.  
  35. def get_neighbors(row, col)
  36. (-1..1).map do |i|
  37. r = row + i
  38. r -= @height if r >= @height
  39. (-1..1).map do |j|
  40. c = col + j
  41. c -= @width if c >= @width
  42. @field[r][c]
  43. end
  44. end
  45. end
  46.  
  47. def count_neighbors(cell, row, col)
  48. neighbors = get_neighbors row, col
  49. neighbors.flatten.count(true) + (cell ? -1 : 0)
  50. end
  51.  
  52. def next_status(row, col)
  53. cell = get_cell row, col
  54. neighbors = count_neighbors cell, row, col
  55. judge cell, neighbors
  56. end
  57.  
  58. def judge(cell, neighbors)
  59. # セルが生存している時 => 周囲の生存セルが2つ or 3つだったら生存し続ける
  60. # セルが死んでいる時 => 周囲の生存セルがちょうど3つだったら生まれる
  61. # それ以外なら死ぬ
  62. cell ? neighbors.between?(2, 3) : neighbors == 3
  63. end
  64.  
  65. def advance #ターンを進める
  66. @turn += 1
  67. @field = Array.new(@height){|row| Array.new(@width){|col| next_status row, col } }
  68. end
  69.  
  70. def active_cells
  71. @field.flatten.count true
  72. end
  73.  
  74. def run(interval = INTERVAL)
  75. puts "\e[2J" #画面消去
  76. loop do
  77. start = Time.now.to_f #更新開始
  78.  
  79. print "\e[1;1H" #1行目の1列目にカーソル移動
  80. print draw #フィールドを出力
  81. print "\e[#{@height};1H" #一番下の行にカーソル移動
  82. print "%5d turn, %5d cells alive. " % [@turn, active_cells] #ステータス行を出力
  83. print "\e[#{@height};#{@width}H" #右下にカーソル移動 (やったほうが美しい)
  84. advance #状態を更新
  85.  
  86. stop = Time.now.to_f #更新終了
  87. elapsed = stop - start #作業にかかった時間
  88.  
  89. #スリープ (画面が大きいと割とモッサリするから作業時間はインターバルからマイナスする)
  90. sleep interval < elapsed ? 0 : interval - elapsed
  91. end
  92. end
  93. end
  94.  
  95. Lifegame.new.run
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement