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 相关文章推荐
JScript中的&quot;this&quot;关键字使用方式补充材料
Mar 08 Javascript
js 图片等比例缩放代码
May 13 Javascript
JavaScript中判断整数的多种方法总结
Nov 08 Javascript
jQuery实现图片渐入渐出切换展示效果
Aug 15 Javascript
js中使用使用原型(prototype)定义方法的好处详解
Jul 04 Javascript
Vue.js仿Metronic高级表格(二)数据渲染
Apr 19 Javascript
使用命令行工具npm新创建一个vue项目的方法
Dec 27 Javascript
vue和webpack打包项目相对路径修改的方法
Jun 15 Javascript
在Vue中获取组件声明时的name属性方法
Sep 12 Javascript
angular4+百分比进度显示插件用法示例
May 05 Javascript
webpack 最佳配置指北(推荐)
Jan 07 Javascript
在Vue 中实现循环渲染多个相同echarts图表
Jul 20 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
《猛禽小队》:DC宇宙的又一超级大烂片
2020/04/09 欧美动漫
yii框架源码分析之创建controller代码
2011/06/28 PHP
php原生导出excel文件的两种方法(推荐)
2016/11/19 PHP
PHP去除空数组且数组键名重置的讲解
2019/02/28 PHP
javascript firefox不显示本地预览图片问题的解决方法
2008/11/12 Javascript
用jQuery简化JavaScript开发分析
2009/02/19 Javascript
js判断样式className同时增加class或删除class
2013/01/30 Javascript
Jquery搜索父元素操作方法
2015/02/10 Javascript
Bootstrap嵌入jqGrid,使你的table牛逼起来
2016/05/05 Javascript
老生常谈JavaScript 正则表达式语法
2016/08/20 Javascript
学习JavaScript图片预加载模块
2016/11/07 Javascript
canvas绘制表盘时钟
2017/01/23 Javascript
Vue 实用分页paging实例代码
2017/04/12 Javascript
layui前段框架日期控件使用方法详解
2017/05/19 Javascript
基于JS对象创建常用方式及原理分析
2017/06/28 Javascript
Angular2学习笔记之数据绑定的示例代码
2018/01/03 Javascript
微信小程序实现抖音播放效果的实例代码
2020/04/11 Javascript
基于vue3.0.1beta搭建仿京东的电商H5项目
2020/05/06 Javascript
微信小程序实现弹幕墙(祝福墙)
2020/11/18 Javascript
[47:39]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 LGD vs OPTIC
2018/03/31 DOTA
pycharm设置鼠标悬停查看方法设置
2019/07/29 Python
解决json中ensure_ascii=False的问题
2020/04/03 Python
python 基于UDP协议套接字通信的实现
2021/01/22 Python
thinkphp5 路由分发原理
2021/03/18 PHP
基于html5实现的图片墙效果
2014/10/16 HTML / CSS
详解移动端Html5页面中1px边框的几种解决方法
2018/07/24 HTML / CSS
美国潜水装备、水肺潜水和浮潜设备商店:Leisure Pro
2018/08/08 全球购物
经济信息管理专业大学生求职信
2013/09/27 职场文书
宿舍违规检讨书
2014/01/12 职场文书
社区庆中秋节活动方案
2014/02/07 职场文书
公司承诺书格式
2014/05/21 职场文书
2014年终工作总结范本
2014/12/15 职场文书
读书笔记格式
2015/07/02 职场文书
vue-cropper插件实现图片截取上传组件封装
2021/05/27 Vue.js
利用python进行数据加载
2021/06/20 Python
Windows server 2012 NTP时间同步的实现
2022/06/25 Servers