-
Notifications
You must be signed in to change notification settings - Fork 0
/
board.rb
134 lines (120 loc) · 3.1 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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
require_relative 'tile.rb'
require 'byebug'
class Board
attr_reader :grid,:height,:width,:bombs
def initialize(level)
if level == "easy"
@height = 9
@width = 9
@bombs = 10
elsif level == "average"
@height = 16
@width = 16
@bombs = 40
elsif level == "test"
@height = 6
@width = 10
@bombs = 9
elsif level == "hard"
@height = 16
@width = 30
@bombs = 99
end
@grid = Array.new(height){Array.new(width){Tile.new}}
end
def num_bombs
@grid.flatten.count{|ele| ele.explode?}
end
def place_random_bombs
while num_bombs < @bombs
position = [rand(0...height),rand(0...width)]
self[position] = Tile.new(true)
end
end
def [](pos)
x,y = pos
@grid[x][y]
end
def []=(pos,value)
x,y = pos
@grid[x][y] = value
end
def render
puts " #{(0...@width).to_a.join(" ")}"
@grid.each_with_index do |row,i|
puts "#{i} #{row.join(" ")}"
end
end
def cheat
puts " #{(0...@width).to_a.join(" ")}"
@grid.each_with_index do |row,i|
row.each do |ele|
if ele.explode?
print " X "
elsif ele.revealed
print " _ "
elsif ele.flagged
print " F "
else
print " #{ele.neighbour_bombs_count} "
end
end
puts
end
end
def valid_pos?(pos)
row, column = pos
row.between?(0,@height-1) && column.between?(0,@width-1)
end
def neighbour(i,j)
tiles = []
row = i - 1
column = j - 1
(row...(row+3)).each do |idx1|
(column...(column+3)).each do |idx2|
pos = [idx1,idx2]
tiles << self[pos] if valid_pos?(pos)
end
end
tiles
end
def bombs_count(area)
area.count{|ele| ele.explode?}
end
def update_neighbour_bombs_count
@grid.each_with_index do |row,i|
row.each_with_index do |tile,j|
area = neighbour(i,j)
tile.neighbour_bombs_count = bombs_count(area)
end
end
end
def reveal_adjacents(pos)
row,column = pos
area = neighbour(row,column)
area.each do |tile|
tile.reveal if tile.neighbour_bombs_count == 0
end
end
def destroyed?
@grid.each do |rows|
return true if rows.any? {|tile| tile.bombed && tile.revealed}
end
return false
end
def cleared?
@grid.all? do |rows|
true if rows.all? {|tile| (tile.bombed && tile.flagged) || (tile.bombed == false)}
end
end
end
if $PROGRAM_NAME == __FILE__
board = Board.new("easy")
board.place_random_bombs
board.cheat
#debugger
board.update_neighbour_bombs_count
puts
board.cheat
board.render
end