-
Notifications
You must be signed in to change notification settings - Fork 0
/
class_minesweeper.js
175 lines (148 loc) · 4.66 KB
/
class_minesweeper.js
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
class Minesweeper
{
static get SIZE() { return 15; }
//
//
// PROPERTIES
rows = 0
columns = 0
bombs = 0
probability_chance = 0
board = [] // cells is a 1d array where each element is another element.
bombsRemainingText
activeGame = false
timerObject
//
//
// METHODS
constructor(timer, rows = Minesweeper.SIZE, columns = Minesweeper.SIZE, probability_chance = 0.1)
{
// PLACE YOUR PROPERTIES BELOW
this.timerObject = timer
this.rows = rows
this.columns = columns
this.probability_chance = probability_chance
// PLACE YOUR PROPERTIES ABOVE
this.board = this.init_board()
this.display_board()
}
init_board()
{
for(let i=0;i<this.columns;i++){
const row = []
for(let j=0; j<this.rows; j++){
let xPos = i
let yPos = j
const newDOMElement = document.createElement("div") // we need an element to display onto the screen. So we create a "div" and pass this to the cell being created.
const newCell = new Cell(xPos, yPos, newDOMElement, this.probability_chance)
row.push(newCell)
}
this.board.push(row)
}
// count the number of bombs that were created. Set bombs variable to the number that were randomly generated.
this.bombs = this.count_bombs()
this.bombsRemainingText = document.querySelector("[bomb-count]")
this.bombsRemainingText.textContent = this.bombs
return this.board
}
display_board()
{
const boardDisplay = document.querySelector("#board")
// we need to set the grid sizing of our board CSS to be consistent wtih the number of rows and columns.
boardDisplay.style.setProperty("--WIDTH", this.columns)
boardDisplay.style.setProperty("--HEIGHT", this.rows)
// and then we add the 'DIV' element of each cell into the HTML of our main page.
this.board.forEach(row => {
row.forEach(cell => {
cell.DOMElement.addEventListener('click', () => {
// when we click on a cell, we need to pass the board in too. The cell needs to calculate what is around it.
// So that it can recursively open the cells that are around it if it is empty.
// if a cell opens and it returns a bomb string, we know that a bomb was just opened and we start the lost condition...
if(cell.openCell(this.board, this.activeGame) === 'bomb')
{
this.lose_gameOver()
}
this.check_for_win()
// and everytime we open a time, we want to check whether the game is over (either clicked a bomb or the last tile was revealed.)
})
cell.DOMElement.addEventListener('contextmenu', e => {
e.preventDefault()
cell.flagCell(this.activeGame)
this.bombs_remaining()
})
boardDisplay.append(cell.DOMElement)
})
})
}
unlock(){
this.activeGame = true
}
// if we reset the game, we simple chance every block back to unopened...
reset(){
this.board.forEach(row => {
row.forEach(cell => {
cell.status = 'unopened'
})
})
// make sure the win/lose condition words are changed back to hidden
const gameOverText = document.querySelector("[game_over]")
gameOverText.textContent = ""
// reset the timer
}
check_for_win()
{
// we check the current board state to see if we have won or lost.
const win = this.win_condition(this.board)
if(win) {
this.activeGame = false
const gameOverText = document.querySelector("[game_over]")
gameOverText.textContent = "WIN"
gameOverText.style.display = "block"
// stop the timer
this.timerObject.stopTimer()
}
}
lose_gameOver(){
this.activeGame = false
const gameOverText = document.querySelector("[game_over]")
gameOverText.textContent = "LOSE"
gameOverText.style.color = 'red';
gameOverText.style.display = "block"
this.timerObject.stopTimer()
}
win_condition(board){
// and then we add the 'DIV' element of each cell into the HTML of our main page.
this.board.forEach(row => {
row.forEach(cell => {
// check whether there are any cells that are still "empty" or "?". You cannot win if that is the case
if(cell.status === 'unopened' || cell.status === '?'){
return false
}
// check whether the current bomb total is 0
if(this.bombsRemainingText !== '0'){
return false
}
// if both are true - you win!
return true
})
})
}
count_bombs(){
let bomb_count = 0
this.board.forEach(row => {
row.forEach(cell => {
if(cell.bomb){
bomb_count ++
}
})
})
return bomb_count
}
bombs_remaining(){
// we need to count the number of flagged cells, and reduce the bomb counter by that number
const flaggedCells = this.board.reduce((sum, row) => {
return sum + row.filter(cell => cell.status === 'flagged').length
}, 0)
this.bombsRemainingText.textContent = this.bombs - flaggedCells
}
}