-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathboard.rb
101 lines (83 loc) · 1.97 KB
/
board.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
92
93
94
95
96
97
98
99
100
101
require './cell'
class Board
def initialize(opts = {})
@width = opts[:width] || 15
@height = opts[:height] || 30
generate_cells!
set_to_alive(opts[:with_alive]) if opts[:with_alive]
seed! if all_cells_are_dead?
end
def cells
@cells ||= @grid.flatten
end
# Seed a random amount of cells to be alive.
def seed!
Random.rand(@width * @height).times do
cells.sample.its_alive!
end
end
# Generates a new board with cells that should be alive.
def generate_new
self.class.new(:height => @height, :width => @width,
:with_alive => coordinates_for_new_cells)
end
# Print the board.
def print
system("clear")
@grid.each do |row|
putc "|"
putc " "
row.each do |cell|
putc cell.to_s
putc " "
end
putc "|"
putc "\n"
end
puts
end
private
# Grabs a cell for given coordinates.
def cell(x, y)
@grid[x][y]
end
# Generate a board of cells.
def generate_cells!
@grid = Array.new(@height) do |i|
Array.new(@width) do |j|
Cell.new(i-1, j-1)
end
end
end
# Sets cells to alive for the given coordinates.
def set_to_alive(coordinates = [])
coordinates.each do |x, y|
cell(x, y).its_alive!
end
end
# Returns an array of coordinates for cells that should be
# alive after the current tick.
def coordinates_for_new_cells
cells.map do |cell|
count = neighbor_count_for_cell(cell)
if cell.alive?
cell.coordinates if count == 2 || count == 3
else
cell.coordinates if count == 3
end
end.compact
end
# Count the number of neighbors for a cell.
def neighbor_count_for_cell(cell)
count = 0
((cell.x - 1)..(cell.x + 1)).each do |i|
((cell.y - 1)..(cell.y + 1)).each do |j|
count +=1 if !cell.at?(i, j) && cell(i, j).alive?
end
end
count
end
def all_cells_are_dead?
cells.select { |c| c.alive? }.count.zero?
end
end