-
Notifications
You must be signed in to change notification settings - Fork 0
/
next.rb
91 lines (74 loc) · 1.99 KB
/
next.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
class Cell
def initialize(prob_of_life)
@alive = prob_of_life > rand
end
def to_s
@alive ? "x" : " " # blank for dead cells
end
def to_i
@alive ? 1 : 0
end
def dead?
!@alive
end
def alive?
@alive
end
end
class Game
def initialize(height, width, prob_of_life)
@height, @width, @prob_of_life = height, width, prob_of_life
@board = Array.new(@height) { Array.new(@width) { Cell.new(prob_of_life) } }
@stats = []
end
def start(steps)
1.upto(steps).each{|step|
next_step
count_live_cells
puts "On step #{step}/#{steps} alive: #{@stats.last} max: #{@stats.max} prob_of_life:#{@prob_of_life} \n======================================"
p self
}
end
def count_live_cells
@stats << @board.flatten.inject(0) { |result, element| result + element.to_i}
end
def next_step
@board.each_with_index{|row, h|
row.each_with_index{|cell, w|
neighbours = get_neighbours_count h,w
# should be extracted out, not sequential, as it is working in realtime, rather than against each step.
if @board[h][w].dead? and neighbours==3
@board[h][w] = Cell.new(1) #born . overkill to create new object each time, todo
else
unless @board[h][w].alive? and (2..3).cover?(neighbours)
@board[h][w] = Cell.new(0) #die
end
end
}
}
end
def to_s
@board.map{|row| row.join}.join("\n")
end
def get_neighbours_count x, y
[
[x + 1, y],
[x - 1, y + 1],
[x, y + 1],
[x - 1, y - 1],
[x, y - 1],
[x + 1, y - 1],
[x - 1, y],
[x + 1, y + 1]
].reject{|element| x_val = element.first
y_val = element.last
x_val >= @width or y_val >= @height or x_val < 0 or y_val < 0 # drop all out of bounds
}.inject(0) { |result, element|
result + @board[element.first][element.last].to_i # count actual neighbours
}
end
end
width, height = 47,47
steps = 1000
prob_of_life = 0.1
Game.new(width, height, prob_of_life).start(steps)