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 相关文章推荐
说说掌握JavaScript语言的思想前提想学习js的朋友可以看看
Apr 01 Javascript
js冒泡法和数组转换成字符串示例代码
Aug 14 Javascript
javascript 实现字符串反转的三种方法
Nov 23 Javascript
Jquery获取和修改img的src值的方法
Feb 17 Javascript
node.js读取文件到字符串的方法
Jun 29 Javascript
18个非常棒的jQuery代码片段
Nov 02 Javascript
JS 终止执行的实现方法
Nov 24 Javascript
Bootstrap Img 图片样式(推荐)
Dec 13 Javascript
Bootstrap Table 在指定列中添加下拉框控件并获取所选值
Jul 31 Javascript
JavaScript基础之流程控制语句的用法
Aug 31 Javascript
10个经典的网页鼠标特效代码
Jan 09 Javascript
vue组件实践之可搜索下拉框功能
Nov 25 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
CentOS6.5 编译安装lnmp环境
2014/12/21 PHP
PHP实现长文章分页实例代码(附源码)
2016/02/03 PHP
php打包网站并在线压缩为zip
2016/02/13 PHP
PHP数学运算与数据处理实例分析
2016/04/01 PHP
php对接java现实加签验签的实例
2016/11/25 PHP
基于 Swoole 的微信扫码登录功能实现代码
2018/01/15 PHP
laravel + vue实现的数据统计绘图(今天、7天、30天数据)
2018/07/31 PHP
使用js正则控制input标签只允许输入的值
2013/07/29 Javascript
js导出txt示例代码
2014/01/14 Javascript
js时间日期格式化封装函数
2014/12/02 Javascript
jquery实现上下左右滑动的方法
2015/02/09 Javascript
jQuery实现3D文字特效的方法
2015/03/10 Javascript
JavaScript中模拟实现jsonp
2015/06/19 Javascript
浅谈javascript函数式编程
2015/09/06 Javascript
JavaScript实现简单的四则运算计算器完整实例
2017/04/28 Javascript
jQuery EasyUI的TreeGrid查询功能实现方法
2017/08/08 jQuery
JS设计模式之访问者模式定义与用法分析
2018/02/05 Javascript
jquery radio 动态控制选中失效问题的解决方法
2018/02/28 jQuery
Angular如何在应用初始化时运行代码详解
2018/06/11 Javascript
H5+C3+JS实现五子棋游戏(AI篇)
2020/05/28 Javascript
layui中select,radio设置不生效的解决方法
2019/09/05 Javascript
jQuery实现的分页插件完整示例
2020/05/26 jQuery
JS实现拖拽元素时与另一元素碰撞检测
2020/08/27 Javascript
Pandas 解决dataframe的一列进行向下顺移问题
2019/12/27 Python
python根据完整路径获得盘名/路径名/文件名/文件扩展名的方法
2020/04/22 Python
农田水利实习自我鉴定
2013/09/19 职场文书
物流创业计划书
2014/02/01 职场文书
七年级历史教学反思
2014/02/05 职场文书
剪彩仪式主持词
2014/03/19 职场文书
手术室护士长竞聘书
2014/03/31 职场文书
医药公司采购员岗位职责
2014/09/12 职场文书
计算机实训报告范文
2014/11/05 职场文书
2015年个人实习工作总结
2015/05/28 职场文书
2020年元旦祝福语录,总有适合你的
2019/12/31 职场文书
解决redis sentinel 频繁主备切换的问题
2021/04/12 Redis
解析Java中的static关键字
2021/06/14 Java/Android