扫雷小游戏已推入gitHub点击此处试玩
欢迎各位体验,菜鸡的练手小项目,轻喷。
同样可在留言处或在线咨询提出您宝贵的意见,祝您玩得愉快
扫雷小游戏通过洗牌算法进行随机布雷,通过用户点击对旁边区域进行搜索判断,达到空白的展开效果
目前游戏中有9*9
,15*15
,20*20
三张地图,后期会加入更多。雷数可自己调节或随机生成
function shuffle() {
for(let i = grids.length-1; i >0 ; i--) {
let randomIndex = Math.floor(Math.random()*(grids.length-1))
let temp = grids[i]
grids[i] = grids[randomIndex]
grids[randomIndex] = temp
}
}
二维数组
正好可以对应上平面中的x轴,y轴所以可把数组分割为二维数组function sliceArray(minColumns) {
let reasonable = grids.length % minColumns == 0 ? true:false
let newColumns = minColumns
columns = minColumns
do {
if(reasonable) {
lines = grids.length/columns
//console.log(grids.length + ' '+ columns + ' ' + lines)
break
} else {
newColumns++
console.log('分行失败,已调整列数为' + newColumns)
reasonable = grids.length % newColumns == 0 ? true:false
}
columns = newColumns
} while (newColumns< 10 + columns)
if(lines == 0){
console.log('棋盘创建失败,请选择合理的棋格数')
} else {
for (let i = 0; i < lines; i++) {
arr.push(grids.slice(i*lines,i*lines+lines))
}
arr.forEach((element, index) => {
element.forEach((ele, inde) =>{
ele.x = index
ele.y = inde
})
})
}
fillNumber(arr, lines, columns) //此处填充数字
for(let i = 0; i < lines; i++){
for(let j = 0; j < columns; j++) {
div = document.createElement('div')
div.index = arr[i][j].id
div.value = arr[i][j].number
div.dirx = arr[i][j].x
div.diry = arr[i][j].y
div.state = arr[i][j].state
div.className = 'grid'
main.appendChild(div)
}
}
main.style.width = 25*lines +2*(lines-1) +'px'
main.style.gridTemplateColumns = 'repeat(' + lines + ', 25px)'
}
function fillNumber(arr, lines, columns) {
let dir = [[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1]]
for(let i = 0; i < lines; i++){
for(let j = 0; j < columns; j++) {
for(let k = 0; k < 8; k++) {
if(i + dir[k][0] < 0 || i+dir[k][0] >= lines || j + dir[k][1] < 0 || j + dir[k][1] >= columns){
continue
}
if(arr[i+dir[k][0]][j+dir[k][1]].sweep == true && arr[i][j].number != 9) {
arr[i][j].number += 1
}
}
}
}
}
事件委托
方式添加点击事件function addClickEvent() {
main.addEventListener('click', (e) => {
switch(e.target.value) {
case 0: scanGrid(e.target); break
case 1: changeState(e.target); addColor(e.target, 'rgb(80, 228, 159)', '#aaa'); break
case 2: changeState(e.target); addColor(e.target, 'rgb(230, 199, 112)', '#aaa'); break
case 3: changeState(e.target); addColor(e.target, 'rgb(239, 243, 30)', '#aaa'); break
case 4:
case 5:
case 6:
case 7:
case 8: changeState(e.target); addColor(e.target, 'rgb(255, 115, 48)', '#aaa'); break
case 9: addColor(e.target, 'rgb(240, 78, 49)' , '#fbb', '?'); gameOver(); break
}
if(count == gridss - sweeps) {
console.log('你获胜了')
mark.style.display = 'block'
}
})
main.addEventListener('contextmenu', (e) =>{
if(e.path.length == 9){
if (e.target.textContent == '?') {
addColor(e.target, '' , '', '')
} else {
addColor(e.target, '' , '', '?')
}
}
e.preventDefault()
})
}
广搜算法解析
function scanGrid(base) {
let dir = [[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1]]
let scanArr = new Array()
arr[base.dirx][base.diry].state = true
count++
scanArr.push(arr[base.dirx][base.diry])
while (scanArr.length != 0){
let element = scanArr.pop()
//console.log(scanArr.length)
divArr[element.x][element.y].style.backgroundColor = '#ccc'
for(let k = 0; k < 8; k++) {
if(element.x + dir[k][0] < 0 || element.x + dir[k][0] >= lines || element.y + dir[k][1] < 0 || element.y + dir[k][1] >= columns){
continue
}
if(arr[element.x+dir[k][0]][element.y+dir[k][1]].state == false && arr[element.x+dir[k][0]][element.y+dir[k][1]].number == 0) {
scanArr.push(arr[element.x+dir[k][0]][element.y+dir[k][1]])
arr[element.x+dir[k][0]][element.y+dir[k][1]].state = true
count++
} else if (arr[element.x+dir[k][0]][element.y+dir[k][1]].state == false && arr[element.x+dir[k][0]][element.y+dir[k][1]].number != 9) {
let a = arr[element.x+dir[k][0]][element.y+dir[k][1]].state == false && arr[element.x+dir[k][0]][element.y+dir[k][1]].number
let a_x = element.x+dir[k][0]
let a_y = element.y+dir[k][1]
arr[a_x][a_y].state = true
count++
switch(a) {
case 1: addColor(divArr[a_x][a_y], 'rgb(80, 228, 159)', '#aaa'); break
case 2: addColor(divArr[a_x][a_y], 'rgb(230, 199, 112)', '#aaa'); break
case 3: addColor(divArr[a_x][a_y], 'rgb(239, 243, 30)', '#aaa'); break
case 4:
case 5:
case 6:
case 7:
case 8: addColor(divArr[a_x][a_y], 'rgb(255, 115, 48)', '#aaa'); break
}
}
}
}
}
function gameOver() {
divs.forEach(element => {
if(element.value == 9){
addColor(element, 'rgb(240, 78, 49)' , '#fbb', '?')
}
});
setTimeout(() => {
mark.style.display = 'block'
}, 1000);
}