-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathminesweeper.nas
332 lines (272 loc) · 8.36 KB
/
minesweeper.nas
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
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
include libs/basiclib
#explain
tempblock air {MBCoords}
msg |
msg Welcome to Minesweeper! Click the &agreen button&S to get started.
delay 1000
tempblock speech {MBCoords}
if explained1 quit
cmd effect explosionsteamsmall 6 1 12 0 0 0
delay 250
tempblock interest 6 1 12
set explained1 true
quit
#explain2
ifnot explained1 quit
tempblock air {MBCoords}
msg |
msg The goal of the game is to clear all of the tiles that do not have mines under them.
msg The number on a cleared tile tells you how many mines are next to it, including diagonals.
delay 1000
tempblock speech {MBCoords}
if explained2 quit
cmd effect explosionsteamsmall 8 1 12 0 0 0
delay 250
tempblock interest 8 1 12
set explained2 true
quit
#explain3
ifnot explained2 quit
tempblock air {MBCoords}
msg |
msg If you suspect a tile has a mine under it, flag it! This helps you keep track and makes it so you can't accidentally click on them.
//msg You can setup hotkeys with &b/input clear&S
//msg &f>&S and &b/input flag&S if you don't want to have to click the buttons.
delay 1000
tempblock speech {MBCoords}
set explained3 true
quit
#input
if runArg1|=|InputMode.Clear goto #setInputMode|clear
if runArg1|=|InputMode.Flag goto #setInputMode|flag
msg Minesweeper: unknown input mode "&o{runArg1}&S"!
msg Minesweeper: Valid input modes: &xclear&S, &xflag
quit
#canStartGame?
set canStart true
if gameState|=|GameState.Playing set canStart false
if gameState|=|GameState.Losing set canStart false
ifnot canStart msg You can't restart the game until you've won or lost.
ifnot canStart terminate
quit
#startGame
clickevent sync register #click
//runargs: board x and y length
set BOARD_X_MAX {runArg1}
set BOARD_Y_MAX {runArg2}
//largest index, aka count -1
setsub BOARD_X_MAX 1
setsub BOARD_Y_MAX 1
set GameState.Playing playing
set GameState.Losing losing
set GameState.Lost lost
set GameState.Won won
set InputMode.Flag flag
set InputMode.Clear clear
set Tile.State.Covered covered
set Tile.State.Uncovered uncovered
set Tile.State.Flagged flagged
set Tile.Block.Mine hotcoals
set Tile.Block.Clear concreteblock
call #canStartGame?
set curTotalCoveredSafeSpaces 0
set hasMoved false
call #Loop2D|#setupTile|0|0|{BOARD_X_MAX}|{BOARD_Y_MAX}
cpemsg bot1 ☻
cpemsg bot3
//cpemsg bot3 Tiles left: &x{curTotalCoveredSafeSpaces}
set gameState {GameState.Playing}
msg Game setup!
msg Left click to &xclear a tile&S.
msg Right click to &xflag a tile&S.
//msg Clear all the tiles that don't have mines under them to win.
//msg The number in a cleared tile tells you how many mines are next to the tile, counting diagonals.
quit
#setInputMode
set inputMode {runArg1}
msg Clicking mode set to: &x{inputMode}
cpemsg bot2 Mode: &x{inputMode}
quit
#click
if gameState|=| msg Game isn't setup yet!
if gameState|=| quit
if gameState|=|GameState.Losing msg The game is over.
if gameState|=|GameState.Losing quit
if gameState|=|GameState.Lost msg The game is over.
if gameState|=|GameState.Lost quit
// click.button
// This can have the value of Left, Right, or Middle
if click.button|=|"Left" set inputMode {InputMode.Clear}
if click.button|=|"Right" set inputMode {InputMode.Flag}
call #clickAt|{MBX}|{MBY}
quit
#clickAt
set x {runArg1}
set y {runArg2}
if inputMode|=|InputMode.Flag goto #tryFlagTile
if inputMode|=|InputMode.Clear goto #tryClearTile|{x}|{y}
msg Choose a clicking mode before clicking a tile!
quit
#setupTile
setrandrange r 0 100
set block {Tile.Block.Clear}
setadd curTotalCoveredSafeSpaces 1
//was 0.2
if r|<=|20 call #isMine
set tile[{xi},{yi}].block {block}
set tile[{xi},{yi}].state {Tile.State.Covered}
tempblock Iron {xi} {yi} 0
quit
#isMine
set block {Tile.Block.Mine}
setsub curTotalCoveredSafeSpaces 1
quit
#tryFlagTile
if tile[{x},{y}].state|=|Tile.State.Covered goto #flagTile
if tile[{x},{y}].state|=|Tile.State.Flagged goto #unflagTile
quit
#flagTile
set tile[{x},{y}].state {Tile.State.Flagged}
tempblock Flagged {x} {y} 0
quit
#unflagTile
set tile[{x},{y}].state {Tile.State.Covered}
tempblock Iron {x} {y} 0
quit
#tryClearTile
set x {runArg1}
set y {runArg2}
ifnot tile[{x},{y}].state|=|Tile.State.Covered quit
call #tryClearTileCore
//If there are no mines around this tile, try to clear everything around it
if curTotalMines|=|0 call #tryFillClear
quit
#tryClearTileCore
cmd effect electric {x} {y} 1 0 0 0
ifnot hasMoved call #checkIfFirstMoveIsMine
set hasMoved true
cpemsg bot1 ═
call #calcNumberOfMinesAroundCell
call #placeTileBlock
if tile[{x},{y}].block|=|Tile.Block.Mine goto #gameOver
setsub curTotalCoveredSafeSpaces 1
cpemsg bot3 Tiles left: &x{curTotalCoveredSafeSpaces}
set tile[{x},{y}].state {Tile.State.Uncovered}
cpemsg bot1 ☻
if curTotalCoveredSafeSpaces|=|0 goto #won
quit
#checkIfFirstMoveIsMine
ifnot tile[{x},{y}].block|=|Tile.Block.Mine quit
setadd curTotalCoveredSafeSpaces 1
set tile[{x},{y}].block {Tile.Block.Clear}
quit
// ---------------------------------------------------------------------------------------- Fill v
//runArgs: x y pos of node
#queueNode
set stack[{stack-count}].x {runArg1}
set stack[{stack-count}].y {runArg2}
setadd stack-count 1
quit
//inserts the last entry of the stack into curNode Vector2 structure
#dequeueNode
setadd stack-count -1
set curNode.x {stack[{stack-count}].x}
set curNode.y {stack[{stack-count}].y}
quit
#tryFillClear
set stack-count 0
call #queueNode|{x}|{y}
#fillLoop
call #dequeueNode
set x {curNode.x}
set y {curNode.y}
setadd x -1
setadd y -1
call #fillBody
setadd x 1
call #fillBody
setadd x 1
call #fillBody
setadd y 1
setadd x -2
call #fillBody
setadd x 1
call #fillBody
setadd x 1
call #fillBody
setadd y 1
setadd x -2
call #fillBody
setadd x 1
call #fillBody
setadd x 1
call #fillBody
setadd y 1
setadd x -2
if stack-count|>|0 jump #fillLoop
//msg Done fill clear.
quit
#fillBody
if x|<|0 quit
if y|<|0 quit
if x|>|BOARD_X_MAX quit
if y|>|BOARD_Y_MAX quit
//msg fill body {x} {y}
//only act on uncleared tiles
ifnot tile[{x},{y}].state|=|Tile.State.Covered quit
//clear the tile
call #tryClearTileCore|{x}|{y}
call #calcNumberOfMinesAroundCell
ifnot curTotalMines|=|0 quit
//only queue to do another round of fill if there's no mines at the spot we just uncovered
call #queueNode|{x}|{y}
quit
// ---------------------------------------------------------------------------------------- Fill ^
#placeTileBlock
set block {tile[{x},{y}].block}
if block|=|Tile.Block.Mine jump #placeIt
if curTotalMines|>|0 set block 484
if curTotalMines|>|0 setadd block curTotalMines
#placeIt
tempblock {block} {x} {y} 0
quit
#calcNumberOfMinesAroundCell
set curTotalMines 0
set xMin {x}
setadd xMin -1
set yMin {y}
setadd yMin -1
set xMax {x}
setadd xMax 1
set yMax {y}
setadd yMax 1
call #Loop2D|#checkMine|{xMin}|{yMin}|{xMax}|{yMax}
//show curTotalMines
quit
#checkMine
if tile[{xi},{yi}].block|=|Tile.Block.Mine setadd curTotalMines 1
quit
#explodeMine
if tile[{xi},{yi}].block|=|Tile.Block.Mine call #doExplosion
quit
#doExplosion
cmd effect explosion {xi} {yi} 0 0 0 0
tempblock {Tile.Block.Mine} {xi} {yi} 0
delay 50
quit
#gameOver
cmd effect explosion {MBCoords} 0 0 0
cpemsg announce &cGAME OVER
msg &cGAME OVER
cpemsg bot1 ┘
msg You died with &x{curTotalCoveredSafeSpaces}&S tiles left to clear.
set gameState {GameState.Losing}
call #Loop2D|#explodeMine|0|0|{BOARD_X_MAX}|{BOARD_Y_MAX}
set gameState {GameState.Lost}
quit
#won
cpemsg announce &aYOU WIN!
msg &aYOU WIN!
cpemsg bot1 ╔
set gameState {GameState.Won}
quit