扫雷简易版-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>

猜你喜欢

转载自blog.csdn.net/qq_41199852/article/details/108010042