javascript实现扫雷简易版


Posted in Javascript onAugust 18, 2020

本文实例为大家分享了javascript实现扫雷简易版的具体代码,供大家参考,具体内容如下

使用截图

javascript实现扫雷简易版

说明

这个完成的建议版本,所以没有插旗子,没有计时,就是最基本的原理实现,熟练的大佬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>

更多有趣的经典小游戏实现专题,分享给大家:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js下用gb2312编码解码实现方法
Dec 31 Javascript
原生js实现淘宝首页点击按钮缓慢回到顶部效果
Apr 06 Javascript
Node.js中的缓冲与流模块详细介绍
Feb 11 Javascript
JavaScript中的DSL元编程介绍
Mar 15 Javascript
JS实现带提示的星级评分效果完整实例
Oct 30 Javascript
jQuery中serializeArray()与serialize()的区别实例分析
Dec 09 Javascript
Jquery Easyui分割按钮组件SplitButton使用详解(17)
Dec 18 Javascript
值得分享和收藏的xmlplus组件学习教程
May 05 Javascript
Webpack中publicPath路径问题详解
May 03 Javascript
微信小程序带动画弹窗组件使用方法详解
Nov 27 Javascript
微信小程序城市选择及搜索功能的方法
Mar 22 Javascript
sortable+element 实现表格行拖拽的方法示例
Jun 07 Javascript
详解Vue的组件中data选项为什么必须是函数
Aug 17 #Javascript
Openlayers实现扩散的动态点(水纹效果)
Aug 17 #Javascript
openLayer4实现动态改变标注图标
Aug 17 #Javascript
openlayers4实现点动态扩散
Aug 17 #Javascript
Vue实现计算器计算效果
Aug 17 #Javascript
vue-model实现简易计算器
Aug 17 #Javascript
Vue实现手机计算器
Aug 17 #Javascript
You might like
php调用自己java程序的方法详解
2016/05/13 PHP
今天你说520了吗?不仅有php表白书还有java表白神器
2016/05/20 PHP
PHP使用Redis替代文件存储Session的方法
2017/02/15 PHP
5款Javascript颜色选择器
2009/10/25 Javascript
jquery 输入框数字限制插件
2009/11/10 Javascript
Jquery实战_读书笔记1—选择jQuery
2010/01/22 Javascript
jquery CSS选择器笔记
2010/03/29 Javascript
jquery 3D球状导航的文章分类
2010/07/06 Javascript
初窥JQuery-Jquery简介 入门了解篇
2010/11/25 Javascript
几种延迟加载JS代码的方法加快网页的访问速度
2013/10/12 Javascript
jQuery判断checkbox(复选框)是否被选中以及全选、反选实现代码
2014/02/21 Javascript
js实现在同一窗口浏览图片
2014/09/17 Javascript
使用jQuery jqPlot插件绘制柱状图
2014/12/18 Javascript
无缝滚动的简单实现代码(推荐)
2016/06/07 Javascript
jQuery制作圣诞主题页面 更像是爱情影集
2016/08/10 Javascript
js仿淘宝评价评分功能
2017/02/28 Javascript
JavaScript对象的特性与实践应用深入详解
2018/12/30 Javascript
vue使用原生swiper代码实例
2020/02/05 Javascript
Python 功能和特点(新手必学)
2015/12/30 Python
Pipenv一键搭建python虚拟环境的方法
2018/05/22 Python
python绘制简单彩虹图
2018/11/19 Python
python实现朴素贝叶斯算法
2018/11/19 Python
浅谈pycharm下找不到sqlalchemy的问题
2018/12/03 Python
Python批量删除只保留最近几天table的代码实例
2019/04/01 Python
selenium+python环境配置教程详解
2019/05/28 Python
python实现合并多个list及合并多个django QuerySet的方法示例
2019/06/11 Python
windows中安装Python3.8.0的实现方法
2019/11/19 Python
Python partial函数原理及用法解析
2019/12/11 Python
将labelme格式数据转化为标准的coco数据集格式方式
2020/02/17 Python
顶级宝石首饰网络零售商:Angara
2016/10/25 全球购物
The North Face北面德国官网:美国著名户外品牌
2018/12/12 全球购物
施华洛世奇新加坡官网:SWAROVSKI新加坡
2020/10/06 全球购物
社区护士演讲稿
2014/08/27 职场文书
经典搞笑版检讨书
2015/02/19 职场文书
2015年政协委员工作总结
2015/05/20 职场文书
人生一定要学会的三样东西:放下、忘记、珍惜
2019/08/21 职场文书