js扫雷 javascript实现扫雷简易版
GMF_CodingBoy 人气:0使用截图
说明
这个完成的建议版本,所以没有插旗子,没有计时,就是最基本的原理实现,熟练的大佬30min就能完成
代码讲解
初始数据
var MAPSIZE = 10; var BOMBNUM = 1; var BOMBPOSITION = {}; var SQUAERPOSITION = {}; var SQUARECHECK = {}; var end = false;
初始化地图(CreateMap())
用BOMBPOSITION这个hash表记录雷的位置,然后生成地图长*地图宽数量的div块然后完成定位,然后用SQUAERPOSITION记录这些div块并且用SQUARECHECK记录当前这些块有没有被点击(记录是否是未开启块)
function CreateMap() { //生成初始的地图 //根据雷的数目生成一个随机雷数目 Create_BOMB(); for (let i = 0; i < MAPSIZE; i++) { for (let j = 0; j < MAPSIZE; j++) { var divEle = document.createElement("div"); divEle.className = "lattice"; divEle.style.top = 20 * i + "px"; divEle.style.left = 20 * j + "px"; divEle.onclick = function () { //这里点击后进行判断 if (end == false) { if (BOMBPOSITION[i + "_" + j] == 1) { //展示所有炸弹的位置 GAMEOVER(); } else { //进行一个递归的更改 Remove(i, j); } } } document.getElementById("container").appendChild(divEle); SQUAERPOSITION[i + "_" + j] = divEle; SQUARECHECK[i + "_" + j] = false; } } }
生成雷(Create_BOMB())
这里的生成就是完善BOMBPOSITION这个hash表
function Create_BOMB() { let bombnum = 0; while (bombnum < BOMBNUM) { let x = _.random(0, MAPSIZE - 1); let y = _.random(0, MAPSIZE - 1); if (BOMBPOSITION[x + "_" + y] == undefined) { BOMBPOSITION[x + "_" + y] = 1; bombnum++; } } }
每个div块的点击事件
游戏结束GAMEOVER()
如果点到了雷就展示所有雷的位置然后游戏结束
function GAMEOVER() { for (let index in BOMBPOSITION) { SQUAERPOSITION[index].innerText = "@" } end = true; }
处理点击的块(Remove())
这个处理是个递归过程,一个div会引起其他div的处理所有要先检查下游戏是不是结束了,如果没结束就遍历周边一圈的块,也就是x - 1 -> x + 1 y - 1 -> y + 1,但是自身就不需要遍历了,这里要注意,然后这些块如果已经被处理过了也不用进行处理,遍历完后如果有雷则在这个块上记录雷数目,如果没有雷那么就将周边块中未遍历的进行Remove()处理,这个过程是一个递归,也可以理解成深度优先级处理。
function Remove(x, y) { if (ISGAMEOVER()) { if (end == false) { alert("游戏结束"); GAMEOVER(); } return; } let Result_Detection = Bomb_Detection(x, y); if (Result_Detection[0].length == 1) { if (Result_Detection[0][0] == 0) { //单纯变颜色 Change(x, y); } else { //更改里面的文字是雷的数目 Change(x, y); SQUAERPOSITION[x + "_" + y].innerText = Result_Detection[0][0]; } } else { //如果没有雷自己先变化然后遍历剩下的 Change(x, y); for (let i = 0; i < Result_Detection.length; i++) { //遍历八个方向剩下的 Remove(Result_Detection[i][0], Result_Detection[i][1]); } //console.log(x + " " + y); //console.log(Result_Detection); } }
检测游戏是否结束(ISGAMEOVER())
就是看一下还有多少块没被处理,如果正好是雷的数目那就游戏结束了
function ISGAMEOVER() { let UsedNum = 0; for (let index in SQUARECHECK) { if (SQUARECHECK[index] == true) { UsedNum++; } } console.log(UsedNum); if (UsedNum == MAPSIZE * MAPSIZE - BOMBNUM) return true; else return false; }
周边遍历(Bomb_Detection())
如果有雷就返回[[Bomb_num]],如果没有雷但是周边的都被遍历过了就返回[[0]],如果没有雷然后有未被遍历过的元素则返回未遍历数组queue[]
function Bomb_Detection(x, y) { let queue = []; let bombnum = 0; for (let i = x - 1; i <= x + 1; i++) { for (let j = y - 1; j <= y + 1; j++) { if ((i != x || j != y)&&Edge_Detection(i,j) == true) { if (BOMBPOSITION[i + "_" + j] == 1) { bombnum++; } else if (SQUARECHECK[i + "_" + j] == false) { queue.push([i, j]); } } } } if (bombnum > 0) { //如果周边有雷 return [ [bombnum] ]; } else if (bombnum == 0 && queue.length == 0) { //如果周边没雷但是所有的都被遍历过了 return [ [0] ]; } else { return queue; } }
边界检测(Edge_Detection())
在遍历周边块的时候要注意,这个周边块需要是合理的
function Edge_Detection(x, y) { //只要在0,0 -> MAPSIZE,MAPSIZE就行 if (x >= 0 && y >= 0 && x < MAPSIZE && y < MAPSIZE) { return true } else { return false } }
处理被处理的块(Change())
如果是周边没有雷那就是变成空白,如果有就写上数字,如果是雷就里面加上@
function Change(x, y) { SQUAERPOSITION[x + "_" + y].className = "lattice2"; SQUARECHECK[x + "_" + y] = true; SQUAERPOSITION[x + "_" + y].style.top = 20 * x + "px"; SQUAERPOSITION[x + "_" + y].style.left = 20 * y + "px"; }
整体代码
<!DOCTYPE html> <html> <head> <title>扫雷</title> <meta charset="utf-8"> <style> .container { left: 200px; height: 200px; width: 200px; position: relative; } .lattice { height: 20px; width: 20px; top: 0px; left: 0px; border-style: solid; border-width: 1px; border-color: #ffffff; background-color: #5E5E5E; position: absolute; color: crimson; } .lattice2 { height: 20px; width: 20px; top: 0px; left: 0px; border-style: solid; border-width: 1px; border-color: #5E5E5E; background-color: #ffffff; position: absolute; color: black; } </style> <script type="text/javascript" src="http://cdn.bootcss.com/lodash.js/4.16.6/lodash.min.js"></script> <script> var MAPSIZE = 10; var BOMBNUM = 1; var BOMBPOSITION = {}; var SQUAERPOSITION = {}; var SQUARECHECK = {}; var end = false; function Init() { CreateMap(); } function CreateMap() { //生成初始的地图 //根据雷的数目生成一个随机雷数目 Create_BOMB(); for (let i = 0; i < MAPSIZE; i++) { for (let j = 0; j < MAPSIZE; j++) { var divEle = document.createElement("div"); divEle.className = "lattice"; divEle.style.top = 20 * i + "px"; divEle.style.left = 20 * j + "px"; divEle.onclick = function () { //这里点击后进行判断 if (end == false) { if (BOMBPOSITION[i + "_" + j] == 1) { //展示所有炸弹的位置 GAMEOVER(); } else { //进行一个递归的更改 Remove(i, j); } } } document.getElementById("container").appendChild(divEle); SQUAERPOSITION[i + "_" + j] = divEle; SQUARECHECK[i + "_" + j] = false; } } } function Create_BOMB() { let bombnum = 0; while (bombnum < BOMBNUM) { let x = _.random(0, MAPSIZE - 1); let y = _.random(0, MAPSIZE - 1); if (BOMBPOSITION[x + "_" + y] == undefined) { BOMBPOSITION[x + "_" + y] = 1; bombnum++; } } } function Remove(x, y) { if (ISGAMEOVER()) { if (end == false) { alert("游戏结束"); GAMEOVER(); } return; } let Result_Detection = Bomb_Detection(x, y); if (Result_Detection[0].length == 1) { if (Result_Detection[0][0] == 0) { //单纯变颜色 Change(x, y); } else { //更改里面的文字是雷的数目 Change(x, y); SQUAERPOSITION[x + "_" + y].innerText = Result_Detection[0][0]; } } else { //如果没有雷自己先变化然后遍历剩下的 Change(x, y); for (let i = 0; i < Result_Detection.length; i++) { //遍历八个方向剩下的 Remove(Result_Detection[i][0], Result_Detection[i][1]); } //console.log(x + " " + y); //console.log(Result_Detection); } } function Change(x, y) { SQUAERPOSITION[x + "_" + y].className = "lattice2"; SQUARECHECK[x + "_" + y] = true; SQUAERPOSITION[x + "_" + y].style.top = 20 * x + "px"; SQUAERPOSITION[x + "_" + y].style.left = 20 * y + "px"; } function GAMEOVER() { for (let index in BOMBPOSITION) { SQUAERPOSITION[index].innerText = "@" } end = true; } function ISGAMEOVER() { let UsedNum = 0; for (let index in SQUARECHECK) { if (SQUARECHECK[index] == true) { UsedNum++; } } console.log(UsedNum); if (UsedNum == MAPSIZE * MAPSIZE - BOMBNUM) return true; else return false; } function Bomb_Detection(x, y) { let queue = []; let bombnum = 0; for (let i = x - 1; i <= x + 1; i++) { for (let j = y - 1; j <= y + 1; j++) { if ((i != x || j != y)&&Edge_Detection(i,j) == true) { if (BOMBPOSITION[i + "_" + j] == 1) { bombnum++; } else if (SQUARECHECK[i + "_" + j] == false) { queue.push([i, j]); } } } } if (bombnum > 0) { //如果周边有雷 return [ [bombnum] ]; } else if (bombnum == 0 && queue.length == 0) { //如果周边没雷但是所有的都被遍历过了 return [ [0] ]; } else { return queue; } } function Edge_Detection(x, y) { //只要在0,0 -> MAPSIZE,MAPSIZE就行 if (x >= 0 && y >= 0 && x < MAPSIZE && y < MAPSIZE) { return true } else { return false } } </script> </head> <body onload="Init()"> <div class="container" id="container"> </div> </body> </html>
更多有趣的经典小游戏实现专题,分享给大家:
加载全部内容