-
Notifications
You must be signed in to change notification settings - Fork 0
/
2013-game-of-life.rb
68 lines (57 loc) · 1.51 KB
/
2013-game-of-life.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# Conway's Game of Life in Ruby #
# http://en.wikipedia.org/wiki/Conway's_Game_of_Life #
# Some code from this excellent article:
# http://rubyquiz.strd6.com/quizzes/193-game-of-life #
class Cell
attr_writer :neighbors
def initialize(seed_probability)
@alive = seed_probability > rand
end
def next!
@alive = @alive ? (2..3) === @neighbors : 3 == @neighbors
end
def to_i
@alive ? 1 : 0
end
def to_s
@alive ? '◉' : ' '
end
end
class Game
def initialize(width, height, seed_probability, steps)
@width, @height, @steps = width, height, steps
@cells = Array.new(height) { Array.new(width) { Cell.new(seed_probability) } }
end
def play!
(1..@steps).each do
sleep(0.05)
next!
system('clear')
puts self
end
end
def next!
@cells.each_with_index do |row, y|
row.each_with_index do |cell, x|
cell.neighbors = alive_neighbours(y, x)
end
end
@cells.each { |row| row.each { |cell| cell.next! } }
end
def alive_neighbours(y, x)
[[-1, 0], [1, 0], # sides
[-1, 1], [0, 1], [1, 1], # over
[-1, -1], [0, -1], [1, -1] # under
].inject(0) do |sum, pos|
sum + @cells[(y + pos[0]) % @height][(x + pos[1]) % @width].to_i
end
end
def to_s
@cells.map { |row| row.join }.join("\n")
end
end
width = (ARGV[0] || 100).to_i
height = (ARGV[1] || 50).to_i
steps = (ARGV[2] || 1000).to_i
seed_probability = (ARGV[3] || 0.5).to_f
Game.new(width, height, seed_probability, steps).play!