手把手教弟弟写了个扫雷demo,弟弟竟拿去跟大学同学装* 附(思路注释+源码)

Posted 贪吃ღ大魔王

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手把手教弟弟写了个扫雷demo,弟弟竟拿去跟大学同学装* 附(思路注释+源码)相关的知识,希望对你有一定的参考价值。

js实现扫雷demo💣

先睹为快:😉

在这里插入图片描述

思路:🌀

  1. 创建地图,随机生成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里面的数字都没有展开
    }
  1. 创建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';
    }
  1. 判断一个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
    }
  1. 如果div在地图中间,周围有八个相邻的div,如果div在四个边界那么分别周围只有5个相邻的div,如果div是在地图四个角落,周围分别只有3个相邻的div
    例:
    在地图中间
    在这里插入图片描述
    在地图边界
    在这里插入图片描述
    在地图四个角落
    在这里插入图片描述

  2. 根据随机一个div在这100个div中是第几个来找出它周围相邻的div
    例:
    在这里插入图片描述
    中间的div是在这100个div 中的第25个,设它的下标为25,那么它正上发的div就是15,它正右边的就是26,它右下角的div就是36,依次类推🍄

  3. 定义一个数组将它周围的div的下标存起来,也就是第几个div,遍历这个数组,判断它周围有几个div 📏

  4. 遍历这个数组的时候需要分情况,也就是div在地图边界和在地图四个角落

  5. 如果div在地图的上边界那个遍历的时候 它的周围不能有 -11 -10 -9的div。如果div在地图的左边界的时候,它的周围不能有-1,9,-11的div。依次类推…

  6. 判断周围div下标是不是真正的地雷,遍历得出他们周围有几个雷的个数,放入在div中
    在这里插入图片描述

  7. 将地雷隐藏起来,给每个div绑定点击事件,左击排雷,右击标雷。如果this是雷,地雷全部爆炸(地雷全部标红,显示地雷),并将所有雷的数字显示出来。

  8. 左键排雷,没有踩雷的话,就把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)

            }
  1. 右击事件标雷,设置蓝色显示
    在这里插入图片描述
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

兄弟俩都是院士!哥哥在南大,弟弟在复旦

# [银联初赛]码队弟弟的求和(数论-分块求和)

过年忽悠弟弟妹妹

银联比赛-B自学图论的码队弟弟

# yyds干货盘点 # 手把手教你使用JavaScript打造一款扫雷游戏