手把手教弟弟写了个扫雷demo,弟弟竟拿去跟大学同学装* 附(思路注释+源码)
Posted 贪吃ღ大魔王
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手把手教弟弟写了个扫雷demo,弟弟竟拿去跟大学同学装* 附(思路注释+源码)相关的知识,希望对你有一定的参考价值。
js实现扫雷demo💣
先睹为快:😉
思路:🌀
- 创建地图,随机生成100个div盒子,设置相应样式
var container = document.querySelector('.container')
// 动态创建100个小div放在container里面
var mineWidth = 50;
var mineHeight = 50;
// 求小div的数量
var mineNum = container.clientWidth * container.clientHeight / (mineWidth * mineHeight)
// 求一行几个
var mineColNum = container.clientWidth / mineWidth;
// 循环创建
for (var i = 0; i < mineNum; i++) {
var div = document.createElement('div')
Tool.setStyle(div, {
width: mineWidth - 2 + "px",
height: mineHeight - 2 + "px",
backgroundColor: "#ccc",
border: "1px solid #fff",
position: "absolute",
left: (i % mineColNum) * mineWidth + "px",
top: parseInt(i / mineColNum) * mineHeight + "px",
textAlign: "center",
lineHeight: "50px"
})
container.appendChild(div)
div.mine = false // 表示所有div初始都不是雷
this.show = false; // 表示所有div里面的数字都没有展开
}
- 创建10个地雷,在地图中位置随机产生💣
// 标记雷
// 定义一个用来存放雷div的下标的数组
var arr = [];
for (var i = 0; i < 10; i++) {
// 获取随机下标
var index = Math.floor(Math.random() * 100)
// 判断数组中是否已经有了这个下标
if (arr.indexOf(index) < 0) {
arr.push(index)
} else {
i--
}
}
// 遍历所有雷div的下标数组,给是雷的div标记
for (var i = 0; i < arr.length; i++) {
container.children[arr[i]].mine = true
// container.children[arr[i]].style.backgroundColor = 'red';
}
- 判断一个div的周围有几个地雷,并将相应的数量给这个div,那么怎么找呢?往以下步骤看
// 定义一个数组,将周围div的下标存起来
var brr = [-11, -10, -9, -1, 1, 9, 10, 11];
// 遍历每个div周围的div
// 遍历这个100个div
for (var i = 0; i < container.children.length; i++) {
// 如果当前这个div是雷就统计了
if (container.children[i].mine) {
continue;
}
// container.children[i] // 每个div
// 查看当前div周围的所有div
// 定义周围雷数量的变量
var num = 0
for (var j = 0; j < brr.length; j++) {
// 考虑最上面一行 - 不能-11 不能-10 不能-9
if (i < mineColNum && (brr[j] === -11 || brr[j] === -10 || brr[j] === -9)) {
continue;
}
// // 最左边一行过滤掉
if (i % mineColNum === 0 && (brr[j] === -11 || brr[j] === -1 || brr[j] === 9)) {
continue;
}
// 最下面一行
if (parseInt(i / mineColNum) === mineColNum - 1 && (brr[j] === 9 || brr[j] === 10 || brr[j] === 11)) {
continue;
}
// 最右边一行
if (i % mineColNum === mineColNum - 1 && (brr[j] === -9 || brr[j] === 1 || brr[j] === 11)) {
continue;
}
if (container.children[i + brr[j]].mine) {
num++
}
}
// 将雷的数量放在div中
container.children[i].num = num
}
-
如果div在地图中间,周围有八个相邻的div,如果div在四个边界那么分别周围只有5个相邻的div,如果div是在地图四个角落,周围分别只有3个相邻的div
例:
在地图中间
在地图边界
在地图四个角落
-
根据随机一个div在这100个div中是第几个来找出它周围相邻的div
例:
中间的div是在这100个div 中的第25个,设它的下标为25,那么它正上发的div就是15,它正右边的就是26,它右下角的div就是36,依次类推
🍄 -
定义一个数组将它周围的div的下标存起来,也就是第几个div,遍历这个数组,判断它周围有几个div 📏
-
遍历这个数组的时候需要分情况,也就是div在地图边界和在地图四个角落
-
如果div在地图的上边界那个遍历的时候 它的周围不能有 -11 -10 -9的div。如果div在地图的左边界的时候,它的周围不能有-1,9,-11的div。依次类推…
-
判断周围div下标是不是真正的地雷,遍历得出他们周围有几个雷的个数,放入在div中
-
将地雷隐藏起来,给每个div绑定点击事件,左击排雷,右击标雷。如果this是雷,地雷全部爆炸(地雷全部标红,显示地雷),并将所有雷的数字显示出来。
-
左键排雷,没有踩雷的话,就把this周围的雷的数量显示出来(显示绿色)
if (this.mine) {
// 如果点击到雷了
for (var j = 0; j < container.children.length; j++) {
// 给所有不是雷的div设置内容显示,雷的数量
container.children[j].innerText = container.children[j].num ? container.children[j].num : '';
container.children[j].style.backgroundColor = '#0f0';
}
// 将所有是雷的div设置为红色
for (var j = 0; j < arr.length; j++) {
container.children[arr[j]].style.backgroundColor = 'red';
}
} else {
// 如果不是雷
// this.innerText = this.num;
// this.style.backgroundColor = '#0f0';
// this.show = true // 表示当前这个div已经展开了
openAround(this.index)
}
- 右击事件标雷,设置蓝色显示
container.children[i].oncontextmenu = function () {
this.style.backgroundColor = 'blue';
return false;
}
}
细节处理: 🚴
- 如果踩雷,将他的内容设为空,而不是undefined。
- 如果踩雷,给所有不是雷的div设置内容显示(绿色,雷的数量),将雷的div设为红色
- 判断自己周围的div是否是0,把周围div打开,用递归将刚刚打开的div继续判断自己是否是0
// 打开周围div的递归函数
function openAround(index) {
container.children[index].innerText = container.children[index].num
container.children[index].style.backgroundColor = '#0f0'
container.children[index].show = true
if (container.children[index].num === 0) {
container.children[index].style.backgroundColor = 'pink';
for (let j = 0; j < brr.length; j++) {
if (index < mineColNum && (brr[j] === -11 || brr[j] === -10 || brr[j] === -9)) {
continue;
}
// // 最左边一行过滤掉
if (index % mineColNum === 0 && (brr[j] === -11 || brr[j] === -1 || brr[j] === 9)) {
continue;
}
// 最下面一行
if (parseInt(index / mineColNum) === mineColNum - 1 && (brr[j] === 9 || brr[j] === 10 || brr[j] === 11)) {
continue;
}
// 最右边一行
if (index % mineColNum === mineColNum - 1 && (brr[j] === -9 || brr[j] === 1 || brr[j] === 11)) {
continue;
}
if (container.children[index + brr[j]].show) {
continue
}
openAround(index + brr[j])
}
}
}
更多详细注释 in 源码 ☕
源码:✨
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>document</title>
</head>
<style>
.container {
width: 500px;
height: 500px;
margin: 50px auto;
border: 3px solid #999;
position: relative;
}
</style>
<body>
<div class="container">
</div>
</body>
<script src="./js/tool.js"></script>
<script>
var container = document.querySelector('.container')
// 动态创建100个小div放在container里面
var mineWidth = 50;
var mineHeight = 50;
// 求小div的数量
var mineNum = container.clientWidth * container.clientHeight / (mineWidth * mineHeight)
// 求一行几个
var mineColNum = container.clientWidth / mineWidth;
// 循环创建
for (var i = 0; i < mineNum; i++) {
var div = document.createElement('div')
Tool.setStyle(div, {
width: mineWidth - 2 + "px",
height: mineHeight - 2 + "px",
backgroundColor: "#ccc",
border: "1px solid #fff",
position: "absolute",
left: (i % mineColNum) * mineWidth + "px",
top: parseInt(i / mineColNum) * mineHeight + "px",
textAlign: "center",
lineHeight: "50px"
})
container.appendChild(div)
div.mine = false // 表示所有div初始都不是雷
this.show = false; // 表示所有div里面的数字都没有展开
}
// 标记雷
// 定义一个用来存放雷div的下标的数组
var arr = [];
for (var i = 0; i < 10; i++) {
// 获取随机下标
var index = Math.floor(Math.random() * 100)
// 判断数组中是否已经有了这个下标
if (arr.indexOf(index) < 0) {
arr.push(index)
} else {
i--
}
}
// 遍历所有雷div的下标数组,给是雷的div标记
for (var i = 0; i < arr.length; i++) {
container.children[arr[i]].mine = true
// container.children[arr[i]].style.backgroundColor = 'red';
}
// 定义一个数组,将周围div的下标存起来
var brr = [-11, -10, -9, -1, 1, 9, 10, 11];
// 遍历每个div周围的div
// 遍历这个100个div
for (var i = 0; i < container.children.length; i++) {
// 如果当前这个div是雷就统计了
if (container.children[i].mine) {
continue;
}
// container.children[i] // 每个div
// 查看当前div周围的所有div
// 定义周围雷数量的变量
var num = 0
for (var j = 0; j < brr.length; j++) {
// 考虑最上面一行 - 不能-11 不能-10 不能-9
if (i < mineColNum && (brr[j] === -11 || brr[j] === -10 || brr[j] === -9)) {
continue;
}
// // 最左边一行过滤掉
if (i % mineColNum === 0 && (brr[j] === -11 || brr[j] === -1 || brr[j] === 9)) {
continue;
}
// 最下面一行
if (parseInt(i / mineColNum) === mineColNum - 1 && (brr[j] === 9 || brr[j] === 10 || brr[j] === 11)) {
continue;
}
// 最右边一行
if (i % mineColNum === mineColNum - 1 && (brr[j] === -9 || brr[j] === 1 || brr[j] === 11)) {
continue;
}
if (container.children[i + brr[j]].mine) {
num++
}
}
// 将雷的数量放在div中
container.children[i].num = num
}
// 点击
for (var i = 0; i < container.children.length; i++) {
container.children[i].index = i
container.children[i].onclick = function () {
if (this.mine) {
// 如果点击到雷了
for (var j = 0; j < container.children.length; j++) {
// 给所有不是雷的div设置内容显示,雷的数量
container.children[j].innerText = container.children[j].num ? container.children[j].num : '';
container.children[j].style.backgroundColor = '#0f0';
}
// 将所有是雷的div设置为红色
for (var j = 0; j < arr.length; j++) {
container.children[arr[j]].style.backgroundColor = 'red';
}
} else {
// 如果不是雷
// this.innerText = this.num;
// this.style.backgroundColor = '#0f0';
// this.show = true // 表示当前这个div已经展开了
openAround(this.index)
爸爸又给Spring MVC生了个弟弟叫Spring WebFlux