1
1
import { Component , ViewChildren , QueryList , AfterViewInit } from "@angular/core" ;
2
2
import { Subscription } from "rxjs" ;
3
- import { TickerService } from "../../services/ticker.service " ;
3
+ import { GameMode } from "../../models/game-mode " ;
4
4
import { GameState } from "../../models/game-state" ;
5
5
import { GameResult } from "../..//models/game-result" ;
6
6
import { BoardPosition } from "../../models/board-position" ;
7
+ import { NormalModeService } from "../../services/normal-mode.service" ;
8
+ import { TrollModeService } from "../../services/troll-mode.service" ;
9
+ import { TickerService } from "../../services/ticker.service" ;
7
10
import { FieldStatus , FieldComponent } from "../field/field.component" ;
8
11
9
12
@Component ( {
@@ -14,22 +17,39 @@ import { FieldStatus, FieldComponent } from "../field/field.component";
14
17
export class GameBoardComponent implements AfterViewInit {
15
18
@ViewChildren ( "field" ) public fieldsList : QueryList < FieldComponent > ;
16
19
public fieldsGrid : FieldComponent [ ] [ ] ;
20
+ private readonly modes : GameMode [ ] ;
17
21
public readonly size : number = 16 ;
18
22
public readonly bombsCount : number = 32 ;
19
23
public flagsLeft : number = this . bombsCount ;
20
24
public seconds : number = 0 ;
21
25
public faceImage : string = "../../../assets/epicface.jpg" ;
22
- protected secondsTicker : Subscription ;
23
- protected state : GameState = GameState . New ;
26
+ private secondsTicker : Subscription ;
27
+ private state : GameState = GameState . New ;
24
28
private score : number = 0 ;
25
-
26
- constructor ( private readonly ticker : TickerService ) { }
29
+ private modeIndex : number = 0 ;
30
+
31
+ constructor (
32
+ private readonly ticker : TickerService ,
33
+ normalMode : NormalModeService ,
34
+ trollMode : TrollModeService
35
+ ) {
36
+ this . modes = [ normalMode , trollMode ] ;
37
+ }
27
38
28
39
public ngAfterViewInit ( ) : void {
29
40
this . fieldsListToGrid ( ) ;
30
41
this . startNewGame ( ) ;
31
42
}
32
43
44
+ public get currentMode ( ) : GameMode {
45
+ return this . modes [ this . modeIndex ] ;
46
+ }
47
+
48
+ public changeMode ( ) : void {
49
+ this . modeIndex = 1 - this . modeIndex ;
50
+ this . ngAfterViewInit ( ) ;
51
+ }
52
+
33
53
public startNewGame ( ) : void {
34
54
if ( this . secondsTicker ) {
35
55
this . secondsTicker . unsubscribe ( ) ;
@@ -38,9 +58,9 @@ export class GameBoardComponent implements AfterViewInit {
38
58
this . state = GameState . New ;
39
59
this . flagsLeft = this . bombsCount ;
40
60
this . seconds = 0 ;
41
- this . faceImage = "../../../assets/epicface.jpg" ;
61
+ this . faceImage = this . currentMode . playingImage ;
42
62
this . score = 0 ;
43
- this . fieldsGrid . forEach ( rw => rw . forEach ( fd => fd . clear ( ) ) ) ;
63
+ this . fieldsGrid . forEach ( row => row . forEach ( field => field . clear ( ) ) ) ;
44
64
this . secondsTicker = this . ticker . create ( ( ) => ++ this . seconds ) ;
45
65
}
46
66
@@ -49,19 +69,31 @@ export class GameBoardComponent implements AfterViewInit {
49
69
this . secondsTicker . unsubscribe ( ) ;
50
70
51
71
if ( result === GameResult . Winning ) {
52
- this . faceImage = "../../../assets/winface.jpg" ;
72
+ this . faceImage = this . currentMode . winningImage ;
53
73
} else {
54
- this . faceImage = "../../../assets/sadface.jpg" ;
55
- this . fieldsGrid . forEach ( rw =>
56
- rw . forEach ( fld => {
57
- if ( fld . hasBomb ) {
58
- fld . status = FieldStatus . Visible ;
74
+ this . faceImage = this . currentMode . losingImage ;
75
+ this . fieldsGrid . forEach ( row =>
76
+ row . forEach ( field => {
77
+ if ( field . hasBomb ) {
78
+ field . status = FieldStatus . Visible ;
59
79
}
60
80
} )
61
81
) ;
62
82
}
63
83
}
64
84
85
+ public onLeftClickFace ( ) : void {
86
+ this . startNewGame ( ) ;
87
+ }
88
+
89
+ public onRightClickFace ( event : MouseEvent ) : void {
90
+ event . preventDefault ( ) ;
91
+
92
+ if ( this . state === GameState . Finished ) {
93
+ this . changeMode ( ) ;
94
+ }
95
+ }
96
+
65
97
public onLeftClickField ( position : BoardPosition ) : void {
66
98
if ( this . state === GameState . Finished ) {
67
99
return ;
@@ -71,7 +103,7 @@ export class GameBoardComponent implements AfterViewInit {
71
103
const bombs : BoardPosition [ ] = this . generateBombs ( position ) ;
72
104
73
105
this . countDistances ( bombs ) ;
74
- this . state = GameState . Played ;
106
+ this . state = GameState . Playing ;
75
107
}
76
108
77
109
const field : FieldComponent = this . fieldsGrid [ position . row ] [ position . column ] ;
@@ -85,12 +117,12 @@ export class GameBoardComponent implements AfterViewInit {
85
117
}
86
118
}
87
119
88
- public onRightClickField ( pos : BoardPosition ) : void {
89
- if ( this . state !== GameState . Played ) {
120
+ public onRightClickField ( position : BoardPosition ) : void {
121
+ if ( this . state !== GameState . Playing ) {
90
122
return ;
91
123
}
92
124
93
- const field : FieldComponent = this . fieldsGrid [ pos . row ] [ pos . column ] ;
125
+ const field : FieldComponent = this . fieldsGrid [ position . row ] [ position . column ] ;
94
126
95
127
if ( field . status === FieldStatus . Hidden && this . flagsLeft > 0 ) {
96
128
-- this . flagsLeft ;
@@ -113,10 +145,6 @@ export class GameBoardComponent implements AfterViewInit {
113
145
}
114
146
}
115
147
116
- private initialBombs ( posClicked : BoardPosition ) : BoardPosition [ ] {
117
- return [ ] ;
118
- }
119
-
120
148
private fieldsListToGrid ( ) : void {
121
149
this . fieldsGrid = new Array < FieldComponent [ ] > ( this . size ) . fill ( null ) ;
122
150
@@ -127,8 +155,8 @@ export class GameBoardComponent implements AfterViewInit {
127
155
this . fieldsList . forEach ( fd => ( this . fieldsGrid [ fd . position . row ] [ fd . position . column ] = fd ) ) ;
128
156
}
129
157
130
- private generateBombs ( posClicked : BoardPosition ) : BoardPosition [ ] {
131
- const bombs : BoardPosition [ ] = this . initialBombs ( posClicked ) ;
158
+ private generateBombs ( positionClicked : BoardPosition ) : BoardPosition [ ] {
159
+ const bombs : BoardPosition [ ] = this . currentMode . initialBombs ( positionClicked ) ;
132
160
133
161
while ( bombs . length < this . bombsCount ) {
134
162
let bombPosition : BoardPosition ;
@@ -140,7 +168,7 @@ export class GameBoardComponent implements AfterViewInit {
140
168
) ;
141
169
} while (
142
170
bombs . findIndex ( p => p . equals ( bombPosition ) ) >= 0 ||
143
- posClicked . isNeighbour ( bombPosition )
171
+ positionClicked . isNeighbour ( bombPosition )
144
172
) ;
145
173
146
174
bombs . push ( bombPosition ) ;
@@ -149,42 +177,42 @@ export class GameBoardComponent implements AfterViewInit {
149
177
return bombs ;
150
178
}
151
179
152
- private countDistances ( bombs : BoardPosition [ ] ) : void {
153
- for ( const pos of bombs ) {
154
- this . fieldsGrid [ pos . row ] [ pos . column ] . createBomb ( ) ;
180
+ private countDistances ( bombPositions : BoardPosition [ ] ) : void {
181
+ for ( const position of bombPositions ) {
182
+ this . fieldsGrid [ position . row ] [ position . column ] . createBomb ( ) ;
155
183
}
156
184
157
- for ( const pos of bombs ) {
158
- if ( pos . row > 0 && pos . column > 0 ) {
159
- this . fieldsGrid [ pos . row - 1 ] [ pos . column - 1 ] . addNeighbouringBomb ( ) ;
185
+ for ( const position of bombPositions ) {
186
+ if ( position . row > 0 && position . column > 0 ) {
187
+ this . fieldsGrid [ position . row - 1 ] [ position . column - 1 ] . addNeighbouringBomb ( ) ;
160
188
}
161
189
162
- if ( pos . row > 0 ) {
163
- this . fieldsGrid [ pos . row - 1 ] [ pos . column ] . addNeighbouringBomb ( ) ;
190
+ if ( position . row > 0 ) {
191
+ this . fieldsGrid [ position . row - 1 ] [ position . column ] . addNeighbouringBomb ( ) ;
164
192
}
165
193
166
- if ( pos . row > 0 && pos . column < this . size - 1 ) {
167
- this . fieldsGrid [ pos . row - 1 ] [ pos . column + 1 ] . addNeighbouringBomb ( ) ;
194
+ if ( position . row > 0 && position . column < this . size - 1 ) {
195
+ this . fieldsGrid [ position . row - 1 ] [ position . column + 1 ] . addNeighbouringBomb ( ) ;
168
196
}
169
197
170
- if ( pos . column > 0 ) {
171
- this . fieldsGrid [ pos . row ] [ pos . column - 1 ] . addNeighbouringBomb ( ) ;
198
+ if ( position . column > 0 ) {
199
+ this . fieldsGrid [ position . row ] [ position . column - 1 ] . addNeighbouringBomb ( ) ;
172
200
}
173
201
174
- if ( pos . column < this . size - 1 ) {
175
- this . fieldsGrid [ pos . row ] [ pos . column + 1 ] . addNeighbouringBomb ( ) ;
202
+ if ( position . column < this . size - 1 ) {
203
+ this . fieldsGrid [ position . row ] [ position . column + 1 ] . addNeighbouringBomb ( ) ;
176
204
}
177
205
178
- if ( pos . row < this . size - 1 && pos . column > 0 ) {
179
- this . fieldsGrid [ pos . row + 1 ] [ pos . column - 1 ] . addNeighbouringBomb ( ) ;
206
+ if ( position . row < this . size - 1 && position . column > 0 ) {
207
+ this . fieldsGrid [ position . row + 1 ] [ position . column - 1 ] . addNeighbouringBomb ( ) ;
180
208
}
181
209
182
- if ( pos . row < this . size - 1 ) {
183
- this . fieldsGrid [ pos . row + 1 ] [ pos . column ] . addNeighbouringBomb ( ) ;
210
+ if ( position . row < this . size - 1 ) {
211
+ this . fieldsGrid [ position . row + 1 ] [ position . column ] . addNeighbouringBomb ( ) ;
184
212
}
185
213
186
- if ( pos . row < this . size - 1 && pos . column < this . size - 1 ) {
187
- this . fieldsGrid [ pos . row + 1 ] [ pos . column + 1 ] . addNeighbouringBomb ( ) ;
214
+ if ( position . row < this . size - 1 && position . column < this . size - 1 ) {
215
+ this . fieldsGrid [ position . row + 1 ] [ position . column + 1 ] . addNeighbouringBomb ( ) ;
188
216
}
189
217
}
190
218
}
@@ -195,95 +223,98 @@ export class GameBoardComponent implements AfterViewInit {
195
223
this . fieldsGrid [ startPos . row ] [ startPos . column ] . status = FieldStatus . Visible ;
196
224
197
225
while ( queue . length > 0 ) {
198
- const pos : BoardPosition = queue . shift ( ) ;
226
+ const position : BoardPosition = queue . shift ( ) ;
199
227
200
- if ( this . fieldsGrid [ pos . row ] [ pos . column ] . isEmpty ) {
228
+ if ( this . fieldsGrid [ position . row ] [ position . column ] . isEmpty ) {
201
229
if (
202
- pos . row > 0 &&
203
- pos . column > 0 &&
204
- this . fieldsGrid [ pos . row - 1 ] [ pos . column - 1 ] . status === FieldStatus . Hidden
230
+ position . row > 0 &&
231
+ position . column > 0 &&
232
+ this . fieldsGrid [ position . row - 1 ] [ position . column - 1 ] . status === FieldStatus . Hidden
205
233
) {
206
- this . fieldsGrid [ pos . row - 1 ] [ pos . column - 1 ] . status = FieldStatus . Visible ;
234
+ this . fieldsGrid [ position . row - 1 ] [ position . column - 1 ] . status = FieldStatus . Visible ;
207
235
208
- if ( ! this . fieldsGrid [ pos . row - 1 ] [ pos . column - 1 ] . hasBomb ) {
209
- queue . push ( new BoardPosition ( pos . row - 1 , pos . column - 1 ) ) ;
236
+ if ( ! this . fieldsGrid [ position . row - 1 ] [ position . column - 1 ] . hasBomb ) {
237
+ queue . push ( new BoardPosition ( position . row - 1 , position . column - 1 ) ) ;
210
238
}
211
239
}
212
240
213
- if ( pos . row > 0 && this . fieldsGrid [ pos . row - 1 ] [ pos . column ] . status === FieldStatus . Hidden ) {
214
- this . fieldsGrid [ pos . row - 1 ] [ pos . column ] . status = FieldStatus . Visible ;
241
+ if (
242
+ position . row > 0 &&
243
+ this . fieldsGrid [ position . row - 1 ] [ position . column ] . status === FieldStatus . Hidden
244
+ ) {
245
+ this . fieldsGrid [ position . row - 1 ] [ position . column ] . status = FieldStatus . Visible ;
215
246
216
- if ( ! this . fieldsGrid [ pos . row - 1 ] [ pos . column ] . hasBomb ) {
217
- queue . push ( new BoardPosition ( pos . row - 1 , pos . column ) ) ;
247
+ if ( ! this . fieldsGrid [ position . row - 1 ] [ position . column ] . hasBomb ) {
248
+ queue . push ( new BoardPosition ( position . row - 1 , position . column ) ) ;
218
249
}
219
250
}
220
251
221
252
if (
222
- pos . row > 0 &&
223
- pos . column < this . size - 1 &&
224
- this . fieldsGrid [ pos . row - 1 ] [ pos . column + 1 ] . status === FieldStatus . Hidden
253
+ position . row > 0 &&
254
+ position . column < this . size - 1 &&
255
+ this . fieldsGrid [ position . row - 1 ] [ position . column + 1 ] . status === FieldStatus . Hidden
225
256
) {
226
- this . fieldsGrid [ pos . row - 1 ] [ pos . column + 1 ] . status = FieldStatus . Visible ;
257
+ this . fieldsGrid [ position . row - 1 ] [ position . column + 1 ] . status = FieldStatus . Visible ;
227
258
228
- if ( ! this . fieldsGrid [ pos . row - 1 ] [ pos . column + 1 ] . hasBomb ) {
229
- queue . push ( new BoardPosition ( pos . row - 1 , pos . column + 1 ) ) ;
259
+ if ( ! this . fieldsGrid [ position . row - 1 ] [ position . column + 1 ] . hasBomb ) {
260
+ queue . push ( new BoardPosition ( position . row - 1 , position . column + 1 ) ) ;
230
261
}
231
262
}
232
263
233
264
if (
234
- pos . column > 0 &&
235
- this . fieldsGrid [ pos . row ] [ pos . column - 1 ] . status === FieldStatus . Hidden
265
+ position . column > 0 &&
266
+ this . fieldsGrid [ position . row ] [ position . column - 1 ] . status === FieldStatus . Hidden
236
267
) {
237
- this . fieldsGrid [ pos . row ] [ pos . column - 1 ] . status = FieldStatus . Visible ;
268
+ this . fieldsGrid [ position . row ] [ position . column - 1 ] . status = FieldStatus . Visible ;
238
269
239
- if ( ! this . fieldsGrid [ pos . row ] [ pos . column - 1 ] . hasBomb ) {
240
- queue . push ( new BoardPosition ( pos . row , pos . column - 1 ) ) ;
270
+ if ( ! this . fieldsGrid [ position . row ] [ position . column - 1 ] . hasBomb ) {
271
+ queue . push ( new BoardPosition ( position . row , position . column - 1 ) ) ;
241
272
}
242
273
}
243
274
244
275
if (
245
- pos . column < this . size - 1 &&
246
- this . fieldsGrid [ pos . row ] [ pos . column + 1 ] . status === FieldStatus . Hidden
276
+ position . column < this . size - 1 &&
277
+ this . fieldsGrid [ position . row ] [ position . column + 1 ] . status === FieldStatus . Hidden
247
278
) {
248
- this . fieldsGrid [ pos . row ] [ pos . column + 1 ] . status = FieldStatus . Visible ;
279
+ this . fieldsGrid [ position . row ] [ position . column + 1 ] . status = FieldStatus . Visible ;
249
280
250
- if ( ! this . fieldsGrid [ pos . row ] [ pos . column + 1 ] . hasBomb ) {
251
- queue . push ( new BoardPosition ( pos . row , pos . column + 1 ) ) ;
281
+ if ( ! this . fieldsGrid [ position . row ] [ position . column + 1 ] . hasBomb ) {
282
+ queue . push ( new BoardPosition ( position . row , position . column + 1 ) ) ;
252
283
}
253
284
}
254
285
255
286
if (
256
- pos . row < this . size - 1 &&
257
- pos . column > 0 &&
258
- this . fieldsGrid [ pos . row + 1 ] [ pos . column - 1 ] . status === FieldStatus . Hidden
287
+ position . row < this . size - 1 &&
288
+ position . column > 0 &&
289
+ this . fieldsGrid [ position . row + 1 ] [ position . column - 1 ] . status === FieldStatus . Hidden
259
290
) {
260
- this . fieldsGrid [ pos . row + 1 ] [ pos . column - 1 ] . status = FieldStatus . Visible ;
291
+ this . fieldsGrid [ position . row + 1 ] [ position . column - 1 ] . status = FieldStatus . Visible ;
261
292
262
- if ( ! this . fieldsGrid [ pos . row + 1 ] [ pos . column - 1 ] . hasBomb ) {
263
- queue . push ( new BoardPosition ( pos . row + 1 , pos . column - 1 ) ) ;
293
+ if ( ! this . fieldsGrid [ position . row + 1 ] [ position . column - 1 ] . hasBomb ) {
294
+ queue . push ( new BoardPosition ( position . row + 1 , position . column - 1 ) ) ;
264
295
}
265
296
}
266
297
267
298
if (
268
- pos . row < this . size - 1 &&
269
- this . fieldsGrid [ pos . row + 1 ] [ pos . column ] . status === FieldStatus . Hidden
299
+ position . row < this . size - 1 &&
300
+ this . fieldsGrid [ position . row + 1 ] [ position . column ] . status === FieldStatus . Hidden
270
301
) {
271
- this . fieldsGrid [ pos . row + 1 ] [ pos . column ] . status = FieldStatus . Visible ;
302
+ this . fieldsGrid [ position . row + 1 ] [ position . column ] . status = FieldStatus . Visible ;
272
303
273
- if ( ! this . fieldsGrid [ pos . row + 1 ] [ pos . column ] . hasBomb ) {
274
- queue . push ( new BoardPosition ( pos . row + 1 , pos . column ) ) ;
304
+ if ( ! this . fieldsGrid [ position . row + 1 ] [ position . column ] . hasBomb ) {
305
+ queue . push ( new BoardPosition ( position . row + 1 , position . column ) ) ;
275
306
}
276
307
}
277
308
278
309
if (
279
- pos . row < this . size - 1 &&
280
- pos . column < this . size - 1 &&
281
- this . fieldsGrid [ pos . row + 1 ] [ pos . column + 1 ] . status === FieldStatus . Hidden
310
+ position . row < this . size - 1 &&
311
+ position . column < this . size - 1 &&
312
+ this . fieldsGrid [ position . row + 1 ] [ position . column + 1 ] . status === FieldStatus . Hidden
282
313
) {
283
- this . fieldsGrid [ pos . row + 1 ] [ pos . column + 1 ] . status = FieldStatus . Visible ;
314
+ this . fieldsGrid [ position . row + 1 ] [ position . column + 1 ] . status = FieldStatus . Visible ;
284
315
285
- if ( ! this . fieldsGrid [ pos . row + 1 ] [ pos . column + 1 ] . hasBomb ) {
286
- queue . push ( new BoardPosition ( pos . row + 1 , pos . column + 1 ) ) ;
316
+ if ( ! this . fieldsGrid [ position . row + 1 ] [ position . column + 1 ] . hasBomb ) {
317
+ queue . push ( new BoardPosition ( position . row + 1 , position . column + 1 ) ) ;
287
318
}
288
319
}
289
320
}
0 commit comments