-
Notifications
You must be signed in to change notification settings - Fork 25
/
script.js
282 lines (252 loc) · 7.79 KB
/
script.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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
// Set this constant to true to debug the placement of bombs without
// having to click on all cells to reveal them.
const CHEAT_REVEAL_ALL = false;
const ROWS_COUNT = 10;
const COLS_COUNT = 10;
const BOMBS_COUNT = 10;
var defeat = false;
var victory = false;
// Cell constructor
function Cell() {
this.discovered = false;
this.isBomb = false;
this.hasBeenFlagged = false;
}
// Initialize cells
var cells = Array(ROWS_COUNT);
for (var row = 0; row < ROWS_COUNT; row++) {
cells[row] = Array(COLS_COUNT);
for (var col = 0; col < COLS_COUNT; col++) {
cells[row][col] = new Cell();
}
}
//
// TODO: Task 1 - add some bombs at fixed positions.
// cells[0][1].isBomb = true;
// cells[5][4].isBomb = true;
// cells[9][9].isBomb = true;
//
// TODO: Task 2 - Comment out the code of task 1. Instead of adding bombs in fixed places, add 10 of them in random places.
// Add a BOMBS_COUNT constant so that you can easily change the amount of bombs placed. Put it next to the
// other constants.
function randCreateBombs(count) {
let numX = 0;
let numY = 0;
for (i = 0; i < count; i++){
numX = Math.floor(Math.random() * COLS_COUNT);
numY = Math.floor(Math.random() * ROWS_COUNT);
cells[numX][numY].isBomb = true;
// console.log(`${numX}x ${numY}y`);
}
}
randCreateBombs(BOMBS_COUNT);
// Once the game has been initialized, we "render" it.
render();
//
// Game functions definitions
//
// let clearedCells = 0;
// console.log(clearedCells);
function discoverCell(row, col) {
//
// TODO: Task 5 - Reveal cells when clicked.
//
cells[row][col].discovered = true;
//
// TODO: Task 6 - Discover neighbor cells recursively, as long as there are no adjacent bombs to the current cell.
//
if (countAdjacentBombs(row, col) === 0) {
//topcell
if(row != 0 && !cells[row-1][col].discovered ){
discoverCell(row-1,col);
}
//rightcell
if(col < COLS_COUNT - 1 && !cells[row][col+1].discovered){
discoverCell(row,col+1);
}
//bootomcell
if(row < ROWS_COUNT - 1 && !cells[row+1][col].discovered){
discoverCell(row+1,col);
}
//leftcell
if(col != 0 && !cells[row][col-1].discovered){
discoverCell(row,col-1);
}
//toprightcell
if(row != 0 && col < COLS_COUNT - 1 && !cells[row-1][col+1].discovered){
discoverCell(row-1,col+1);
}
//bottomrightcell
if(col < COLS_COUNT - 1 && row < ROWS_COUNT - 1 && !cells[row+1][col+1].discovered){
discoverCell(row+1,col+1);
}
//bottomleftcell
if(col != 0 && row < ROWS_COUNT - 1 && !cells[row+1][col-1].discovered){
discoverCell(row+1,col-1);
}
//topleftcell
if(row != 0 && col != 0 && !cells[row-1][col-1].discovered){
discoverCell(row-1,col-1);
}
}
//
// TODO: Task 8 - Implement defeat. If the player "discovers" a bomb (clicks on it without holding shift), set the variable defeat to true.
//
if (cells[row][col].isBomb) {
defeat = true;
}
}
function flagCell(row, col) {
//
// TODO: Task 7 - Implement flags. Flags allow the player to mark cells that they think contain a bomb.
// When clicking a cell and holding shift, function flagCell() will be called for you.
//
cells[row][col].hasBeenFlagged = true;
}
// This function is called once for each cell when rendering the game. The row and col of the current cell is
// passed to the functionn
function countAdjacentBombs(row, col) {
//
// TODO: Task 4 - Adjacent bombs are bombs in cells touching our cell (also diagonally). Implement this function
// so that it returns the count of adjacent cells with bombs in them.
let count = 0;
//topcell
if(row != 0 && cells[row-1][col].isBomb){
count += 1;
}
//rightcell
if(col < COLS_COUNT - 1 && cells[row][col+1].isBomb){
count += 1;
}
//bootomcell
if(row < ROWS_COUNT - 1 && cells[row+1][col].isBomb){
count += 1;
}
//leftcell
if(col != 0 && cells[row][col-1].isBomb ){
count += 1;
}
//toprightcell
if(row != 0 && col < COLS_COUNT - 1 && cells[row-1][col+1].isBomb){
count += 1;
}
//bottomrightcell
if(col < COLS_COUNT - 1 && row < ROWS_COUNT - 1 && cells[row+1][col+1].isBomb){
count += 1;
}
//bottomleftcell
if(col != 0 && row < ROWS_COUNT - 1 && cells[row+1][col-1].isBomb){
count += 1;
}
//topleftcell
if(row != 0 && col != 0 && cells[row-1][col-1].isBomb){
count += 1;
}
return count;
}
function getBombsCount() {
//
// TODO: Task 9 - Implement stats: the counters currently always display 0, calculate and return the relevant values.
//
return BOMBS_COUNT;
}
function getClearedCells() {
//
// TODO: Task 9 - Implement stats: the counters currently always display 0, calculate and return the relevant values.
//
// for (let index = 0; index < cells.length; index++) {
// const element = array[index];
// }
return 0;
}
function getTotalCellsToClear() {
//
// TODO: Task 9 - Implement stats: the counters currently always display 0, calculate and return the relevant values.
//
return 0;
}
function checkForVictory() {
//
// TODO: Task 10 - Implement victory. If the player has revealed as many cells as they must (every cell that isn't a
// bomb), set variable victory to true.
//
return 0;
}
//
// Rendering functions
//
function getMessage() {
if (victory == true) {
return "Well done! 👏🏼<br><br>Refresh the page to start again.";
} else if (defeat) {
return "Boom! 💥<br><br>Refresh the page to try again.";
}
return "";
}
// "Render" the game. Update the content of the page to reflect any changes to the game state.
function render() {
var playfield = document.getElementById("playfield");
var html = "";
for (var row = 0; row < ROWS_COUNT; row++) {
html += '<div class="row">';
for (var col = 0; col < COLS_COUNT; col++) {
var cell = cells[row][col];
var cellText = "";
var cssClass = "";
var textColor = "";
if (cell.discovered || CHEAT_REVEAL_ALL || defeat) {
cssClass = "discovered";
if (cell.isBomb) {
cellText = "💣";
} else {
var adjBombs = countAdjacentBombs(row, col);
if (adjBombs > 0) {
cellText = adjBombs.toString();
if (adjBombs == 1) {
textColor = "blue";
} else if (adjBombs == 2) {
textColor = "green";
} else if (adjBombs == 3) {
textColor = "red";
} else if (adjBombs == 4) {
textColor = "black";
}
}
}
} else {
if (cell.hasBeenFlagged) {
cellText = "🚩"
}
}
html += `<div class="cell ${cssClass}" style="color:${textColor}" onclick="onCellClicked(${row}, ${col}, event)">${cellText}</div>`;
}
html += "</div>"
}
playfield.innerHTML = html;
// Defeat screen
var body = document.getElementsByTagName("body")[0];
if (defeat) {
body.classList.add("defeat")
}
// Victory screen
if (victory) {
body.classList.add("victory")
}
// Update stats
document.getElementById("bombs-count").innerText = getBombsCount().toString();
document.getElementById("cleared-cells-count").innerText = getClearedCells().toString();
document.getElementById("total-cells-to-clear").innerText = getTotalCellsToClear().toString();
// Update message
document.getElementById("message").innerHTML = getMessage();
}
// This function gets called each time a cell is clicked. Arguments "row" and "col" will be set to the relevant
// values. Argument "event" is used to check if the shift key was held during the click.
function onCellClicked(row, col, event) {
if (event.shiftKey) {
flagCell(row, col);
} else {
discoverCell(row, col);
}
checkForVictory();
render();
}