forked from caijinyc/game-mineSweepinng
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjin.js
367 lines (346 loc) · 13 KB
/
jin.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
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
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
/*
扫雷游戏:
初级:10个 9*9
中级:40个 16*16
高级:99个 28*28
第一步:
输出一个
[
[1, 9, 2, 1],
[2, 4, 9, 2],
[9, 4, 9, 2],
[2, 9, 2, 1],
]
这样的数组,其中需要的数值有:1,雷的数量 2,行数和列数
实现步骤:
1,根据行数和列数创建一个多维数组(使用 for 循环嵌套实现)
2,然后使用 Math 随机 a[x][x] 来写入雷的位置(再次使用 for 循环,写入 1)
如果位置已经有雷了就重写随机然后写入
3,bibibibibi --> 实现上述的数组
过程:1,先生成一行
2,复制成列
3.塞入雷
4.写一个函数实现:如果数组位置上的值为 1 的话,就给边上一圈的值加 1,
第二步:
进行操作:
当点击到 0 的值的时候,
开始遍历边上一圈的值(打开所有边上的值),如果值也是 0 的话,就接着遍历边上一圈的值,直到没有为止。
这里可以写一个函数,当点击到 0 的时候就用这个函数,然后给边上还是 0 的继续使用这个函数
*/
// 1,成一张雷的地图
var mineSweepingMap = function (r, c, num) {
var map = []
// 给行数,生成一个 1 维数组
var row = function (r) {
for (var i = 0; i < r; i++) {
map[i] = new Array()
}
}
// 给列数,生成一个 2 维数组
var column = function (col) {
for (var i = 0; i < map.length; i++) {
for (var j = 0; j < col; j++) {
map[i][j] = 0
}
}
}
// 给列数和行数生成空地图
var blankMap = function (r, col) {
row(r)
column(col)
}
// 给出地雷数量让后随机写入地雷
var writeInMine = function (num) {
// 随机位置写入
var randomLocation = function () {
var x = Math.floor(Math.random() * r)
var y = Math.floor(Math.random() * c)
// console.log( ':', x, y);
if (map[x][y] !== 9) {
map[x][y] = 9
} else {
randomLocation()
}
}
for (var i = 0; i < num; i++) {
randomLocation()
}
}
// 使用循环给雷的边上所有数 +1 , 已经是雷的除外
var plus = function (array, x, y) {
if (x >= 0 && x < r && y >= 0 && y < c) {
if (array[x][y] !== 9) {
array[x][y] += 1
}
}
}
var writeInHint = function () {
for (var x = 0; x < map.length; x++) {
for (var y = 0; y < map[0].length; y++) {
if (map[x][y] === 9) {
// 上下 6 个
for (var i = -1; i < 2; i++) {
plus(map, x - 1, y + i)
plus(map, x + 1, y + i)
}
// 左右 2 个
plus(map, x, y + 1)
plus(map, x, y - 1)
}
}
}
}
blankMap(r, c)
writeInMine(num)
writeInHint()
return map
}
// 2,将雷写入页面
var writeHtml = function (map) {
// 先通过 y轴数量写入 ul,然后通过 x轴上的数量写入 li
var x = document.querySelector('.gameBox')
for (var i = 0; i < map.length; i++) {
x.innerHTML = x.innerHTML + `<ul class="row x-${i}" data-x="${i}"></ul>`
}
var z = document.querySelectorAll('.row')
for (var i = 0; i < z.length; i++) {
for (var j = 0; j < map[0].length; j++) {
var m = map[i][j]
if (m === 0) {
m = ''
}
z[i].innerHTML = z[i].innerHTML + `
<li class="col y-${j} num-${m}" data-y="${j}">
<span>${m}</span>
<img src="flag.svg" class="img-flag hide">
</li>`
}
}
}
// 判断是否胜利
var changeClearMineNum = function (clearMineNum) {
// console.log('zmzmzmzm');
// console.log('zz', zz);
if (clearMineNum === ((col * row) - num)) {
var all = document.querySelectorAll('.col')
var allNum = 0
var stop = setInterval(function () {
var r = Math.floor(Math.random() * 256)
var g = Math.floor(Math.random() * 256)
var b = 210
// var b = Math.floor(Math.random() * 256)
all[allNum].children[0].style.opacity = `0`
all[allNum].children[1].style.opacity = '0'
all[allNum].style.background = `rgba(${r},${g},${b},0.6)`
allNum++
if (allNum === all.length) {
clearInterval(stop)
if (zz === 0) {
alert('你成功啦~!!晚上吃肉~~!')
initializeGame(row, col, num)
}
initializeGame(row, col, num)
}
}, 20)
}
}
// 3,扫雷过程
var clearMine = function (row, col, num) {
var clearMineNum = 0
var makeWhite = function (x, y) {
if (x < row && y < col && x >= 0 && y >= 0) {
var el = document.querySelector(`.x-${x}`).children[y]
// 需要注意这个 !== 'white' ,如果不加这个就会进入无限循环
if (el.style.background !== 'white') {
el.style.background = 'white'
el.children[0].style.opacity = '1'
el.children[1].classList.add('hide')
clearMineNum++
// console.log(clearMineNum, 'clearMineNum');
changeClearMineNum(clearMineNum)
if (el.innerText === '') {
showNoMine(x, y)
}
}
}
}
// 智能扫雷
var showNoMine = function (x, y) {
// console.log(x, y, 'x,y');
makeWhite(x - 1, y + 1)
makeWhite(x - 1, y - 1)
makeWhite(x - 1, y)
makeWhite(x + 1, y + 1)
makeWhite(x + 1, y - 1)
makeWhite(x + 1, y)
makeWhite(x, y + 1)
makeWhite(x, y - 1)
}
// 给所有方块绑定点击事件,点击显示数字,或者 boom
var show = function () {
// var x = document.querySelectorAll('.col')
var x = document.querySelectorAll('.row')
for (var i = 0; i < x.length; i++) {
x[i].addEventListener('click', function (event) {
var el = event.target
if (el.tagName != 'LI') {
// 因为事件委托的原因
// 如果点击到了 span 上面,那么就会出现 bug
// 所以如果点击到 span 上面,那么 el 就等于 span 的父节点
el = event.target.parentElement
}
// 已经被标记的不能点击
var flag = el.children[1].classList.contains('hide')
if (el.tagName === 'LI' && flag) {
if (el.children[0].innerText !== '9' && el.style.background !== 'white') {
el.children[0].style.opacity = '1'
el.style.background = 'white'
clearMineNum++
changeClearMineNum(clearMineNum)
// console.log(clearMineNum, 'clearMineNum');
} else if (el.children[0].innerText === '9') {
// el.children[0].style.opacity = '1'
zz = 1
el.classList.add('boom')
alert('游戏失败')
var all = document.querySelectorAll('.col')
var ff = []
var allNum = 0
// 这里做了个小动画,失败的时候慢慢的显示雷的位置
for (var i = 0; i < all.length; i++) {
if (all[i].children[0].innerText === '9') {
// all[i].style.background = 'red'
ff[allNum] = all[i]
allNum++
}
}
allNum = 0
var time = 60
if (num > 50) {
time = 10
} else if (num > 10) {
time = 25
}
var stop = setInterval(function () {
ff[allNum].classList.add('boom')
allNum++
if (allNum === ff.length) {
clearInterval(stop)
// console.log('stop');
}
}, time)
// var box = document.querySelector('.gameBox')
// box.innerHTML = ''
// var level = event.target.innerHTML
// var body = document.querySelector('body')
// initializeGame(row, col, num)
}
// 如果点击的方格为空(什么有没有),那么周围没有点开的空方格都会被点开
if (el.children[0].innerText === '') {
// 获取到位置
var x = parseInt(el.parentElement.dataset.x)
var y = parseInt(el.dataset.y)
// console.log(x,y, 'data');
// 背景变成白色
showNoMine(x, y)
}
}
})
}
for (var i = 0; i < x.length; i++) {
var mineNum = num
x[i].addEventListener('contextmenu', function (event) {
event.preventDefault();
var btnNum = event.button
var el = event.target
if (el.tagName != 'LI') {
// 因为事件委托的原因
// 如果点击到了 span 上面,那么就会出现 bug
// 所以如果点击到 span 上面,那么 el 就等于 span 的父节点
el = event.target.parentElement
}
if (el.tagName === 'LI') {
var classList = el.children[1].classList
// 已经被点击过的地方不能标记
if (classList.contains('hide') && el.style.background !== 'white') {
var residue = document.querySelector('.residue')
if (mineNum !== 0) {
mineNum--
}
residue.innerText = `${mineNum}`
classList.remove('hide')
} else if (el.style.background !== 'white') {
classList.add('hide')
}
}
})
}
}
show()
}
// 4,清除画面,然后写入新的画面
var stopTime
var initializeGame = function (row, col, num) {
var residue = document.querySelector('.residue')
residue.innerText = `${num}`
var time = document.querySelector('.tick')
time.innerText = `0`
var i = 1
clearInterval(stopTime)
stopTime = setInterval(function () {
time.innerText = `${i++}`
}, 1000)
// zz
zz = 0
// 首先清除原来的地图,然后重新初始化
var box = document.querySelector('.gameBox')
box.innerHTML = ''
var body = document.querySelector('body')
body.style.minWidth = `${27 * col}px`
var map = mineSweepingMap(row, col, num)
writeHtml(map)
clearMine(row, col, num)
}
// 5,选择游戏等级,给按钮绑定功能
var Btn = function () {
var level = document.querySelectorAll('.choice-level')
for (var i = 0; i < level.length; i++) {
level[i].addEventListener('click', function (event) {
var level = event.target.innerHTML
if (level === '初级') {
row = 9
col = 9
num = 10
initializeGame(row, col, num)
} else if (level === '中级') {
row = 16
col = 16
num = 40
initializeGame(row, col, num)
} else if (level === '高级') {
row = 16
col = 30
num = 99
initializeGame(row, col, num)
}
})
}
var restart = document.querySelector('.restart')
restart.addEventListener('click', function (event) {
initializeGame(row, col, num)
})
}
Btn()
// 6,初始数据
// zz 用来确定是否已经点到地雷
var zz = 0
var row = 16
var col = 16
var num = 40
initializeGame(row, col, num)
// 给一个坐标,把四周变成白色
// 根据
// 绑定鼠标右击事件,右击鼠标的时候进行标记,
// 这个时候要进行 css 的变化
// 当所有地雷被标记,或者说所有数组中只剩 9,游戏成功。
// 选择游戏难度