js implements the classic minesweeper game

js implements the classic minesweeper game

This article example shares the specific code of js to implement the classic minesweeper game for your reference. The specific content is as follows

Project Structure

Achieve results

Thought Process

1. Write out the basic layout
2. Use js to generate a table for minesweeping
3. Use random numbers to index mines in the table
4. Initialize the table
5. Generate numbers around mines based on their coordinates
6. Click events are divided into left mouse button click and right mouse button click
7. Left-clicking can be divided into two situations: clicking on a mine or not clicking on a mine.
8. If you click on a mine, all mines will be displayed, other styles remain unchanged, and you can no longer perform any click events in any table (neither left nor right clicks work)
9. If the number you clicked is not a mine, it can be divided into two cases: the number you clicked is 0 and the number you clicked is not 0.
10. If it is non-zero, only the number needs to be displayed
11. If it is 0, use recursion to traverse the surrounding tables. If it is 0, continue to recursively display 0 until a non-zero value is encountered.
12. Continuing from step 6 above, if you right-click, a small red flag will be displayed, and the number of remaining mines will be -1.
13. When the number of remaining mines is 0, determine whether there are all mines under the small red flag. If there are all mines, the minesweeper is successful, otherwise the minesweeper fails.
14. Add functions to the buttons, 9 times 9->10 mines, 16 times 16->40 mines, 28 times 28, 99 mines, and a restart button

HTML source code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/style.css" rel="external nofollow" >
</head>

<body>
    <div class="footer">Number of mines remaining: <span class="mineNum"></span></div>
    <div class="gameBox">

    </div>
    <div class="header">
        <button class="active">Primary</button>
        <button>Intermediate</button>
        <button>Advanced</button>
        <button>Restart</button>
    </div>
    <script src="./js/main.js"></script>
</body>
</html>

CSS Style Sheet

* {
    padding: 0;
    margin: 0;
}

.header {
    margin: 10px auto auto auto;
    text-align: center;
}

.header button {
    padding: 5px 15px;
    background-color: #02a4ad;
    color: #fff;
    text-align: center;
    border: none;
    border-radius: 8px;
    outline: none;
    cursor: pointer;
}

.header button.active {
    background-color: #00abff;
}

.footer {
    margin: 100px auto auto auto;
    text-align: center;
}



table {
    margin: 10px auto auto auto;
    border-spacing: 1px;
    background: #929196;
}

td {
    padding: 0;
    width: 20px;
    height: 20px;
    border: 2px solid;
    background: #ccc;
    border-color: #fff #a1a1a1 #a1a1a1 #fff;
    text-align: center;
    line-height: 20px;
    font-weight: 700;
}

.mine {
    background: #d9d9d9 url(../images/mine01.jpg) no-repeat center;
    background-size: cover;
}

.flag {
    background: #fff url(../images/flag.jpeg) no-repeat center;
    background-size: cover;
}

.redMine {
    background: #fff url(../images/mine02.jpg) no-repeat center;
    background-size: cover;
}

td.zero{
 border-color: #d9d9d9;
 background: #d9d9d9;
}
td.one{
 border-color: #d9d9d9;
 background: #d9d9d9;
 color: #0332fe;
}
td.two{
 border-color: #d9d9d9;
 background: #d9d9d9;
 color: #019f02;
}
td.three{
 border-color: #d9d9d9;
 background: #d9d9d9;
 color: #ff2600;
}
td.four{
 border-color: #d9d9d9;
 background: #d9d9d9;
 color: #93208f;
}
td.five{
 border-color: #d9d9d9;
 background: #d9d9d9;
 color: #ff7f29;
}
td.six{
 border-color: #d9d9d9;
 background: #d9d9d9;
 color: #ff3fff;
}
td.seven{
 border-color: #d9d9d9;
 background: #d9d9d9;
 color: #3fffbf;
}
td.eight{
 border-color: #d9d9d9;
 background: #d9d9d9;
 color: #22ee0f;
}

js source code

function Mine(tr, td, mineNum) {
    this.tr = tr; // row this.td = td; // column this.mineNum = mineNum; // number of mines this.squares = []; // square object array this.tds = []; // square DOM
    this.surplusMine = mineNum; // The remaining number of mines this.mainBox = document.querySelector('.gameBox'); // Get the game box element //this.createDom();
}

/*Generate random numbers*/
Mine.prototype.randomNum = function () {
    var positionArray = new Array(this.tr * this.td);
    for (var i = 0; i < positionArray.length; i++) { // Use the index to determine the position of the mine positionArray[i] = i
    }
    // Array shuffle positionArray.sort(function () {
        return 0.5 - Math.random()
    });
    return positionArray.splice(0, this.mineNum); // Take the random mineNum numbers as the mine positions}

// Initialization Mine.prototype.init = function () {
    var positionMine = this.randomNum(); // Get the position of the mine var n = 0;
    for (var i = 0; i < this.tr; i++) {
        this.squares[i] = [];
        for (var j = 0; j < this.td; j++) {
            if (positionMine.indexOf(n++) != -1) { // Use indexOf to put the mine into the square array this.squares[i][j] = { type: 'mine', x: j, y: i };
            } else {
                this.squares[i][j] = { type: 'number', x: j, y: i, value: 0 };
            }
        }
    }

    this.mainBox.oncontextmenu = function () {
        return false;
    }

    this.updateNum();
    this.createDom();
    //console.log(this.squares);

    // Process the remaining mine numbers this.mineNumDom = document.querySelector('.mineNum');
    this.surplusMine = this.mineNum;
    this.mineNumDom.innerHTML = this.surplusMine;

    // Process game prompts //document.querySelector('');

};

/*Generate a large table*/
Mine.prototype.createDom = function () {
    var This = this; // The function is to point to the instance object var table = document.createElement('table'); // Create a table
    for (var i = 0; i < this.tr; i++) {
        var domTr = document.createElement('tr'); // Create row tr
        this.tds[i] = []; // store [[],[],[]...[]] rows for (var j = 0; j < this.td; j++) {
            var domTd = document.createElement('td'); // Create column td
            domTd.pos = [i, j];
            domTd.onmousedown = function () {
                This.play(event, this);
            };
            this.tds[i][j] = domTd; // Storage columns [ [,],[,], [,] .....]
            domTr.appendChild(domTd); // Add columns to the row}
        table.appendChild(domTr) // Add a grid to the table}

    // Clear the previous state this.mainBox.innerHTML = '';
    this.mainBox.appendChild(table); // Form a large square tr*td
}

// Find the grid Mine.prototype.getAround = function (positionArray) {
    var x = positionArray.x;
    var y = positionArray.y;
    var result = []; // 2D, each child found is returned/* The coordinate information here is as follows x-1,y-1 x,y-1 x+1,y-1
        x-1,yx,y x+1,y
        x-1,y+1 x,y+1 x+1,y+1
    */
    for (var i = x - 1; i <= x + 1; i++) {
        for (var j = y - 1; j <= y + 1; j++) {
            if (
                i < 0 || // Beyond the left side of the table j < 0 || // Beyond the top i > this.td - 1 || // Beyond the right side of the table j > this.tr - 1 || // Beyond the bottom of the table (i == x && j == y || // Click point itself this.squares[j][i].type == 'mine') // If it is a mine, there is no need to modify the value) {
                continue;
            }
            result.push([j, i]); // Add surrounding grid information to the result array, such as the jth row and the ith column have numbers}
    }

    return result; // Return grid information array}


// Update number Mine.prototype.updateNum = function () {
    for (var i = 0; i < this.tr; i++) {
        for (var j = 0; j < this.td; j++) {
            // Just need to update the numbers around Lei if (this.squares[i][j].type == 'number') {
                continue;
            }
            var num = this.getAround(this.squares[i][j]);
            for (var k = 0; k < num.length; k++) {
                // If there are mines around the number, add 1
                this.squares[num[k][0]][num[k][1]].value += 1;
            }
        }
    }
}


Mine.prototype.play = function (ev, obj) {
    var This = this; // Get the instance object // The left button is clicked which=1 is the left button, 2 is the middle scroll wheel, 3 is the right button if (ev.which == 1 && obj.className != 'flag') {

        var curSquare = this.squares[obj.pos[0]][obj.pos[1]];
        // Styles for each number var cl = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'];

        // The clicked number if (curSquare.type == 'number') {
            obj.innerHTML = curSquare.value;
            obj.className = cl[curSquare.value];

            // The numbers you click on can be divided into two types, 0 and non-0
            // 1. Click on the number 0
            if (curSquare.value == 0) {
                obj.innerHTML = ''; // Do not display the digital style of 0

                function getAllZero(positionArray) {
                    // Get the surrounding grid information var around = This.getAround(positionArray);

                    // Using recursive thinking, make the surrounding grid 0 not display, and stop when it is not 0 for (var i = 0; i < around.length; i++) {
                        // around[i]=[0,0]
                        var x = around[i][0];
                        var y = around[i][1];

                        This.tds[x][y].className = cl[This.squares[x][y].value];

                        // If it is still 0
                        if (This.squares[x][y].value == 0) {
                            // Recursive if (!This.tds[x][y].check) {
                                This.tds[x][y].check = true;

                                getAllZero(This.squares[x][y]);
                            }
                        } else {
                            // If it is not 0, continue to display the number This.tds[x][y].innerHTML = This.squares[x][y].value;
                        }
                    }
                }

                getAllZero(curSquare);

            }
        } else {
            // Clicked a mine, directly judge the game is over this.gameOver(obj);
        }
    }
    // which=3, the mouse clicked the right button if (ev.which == 3) {
        if (obj.className && obj.className != 'flag') {
            return;
        }
        obj.className = obj.className == 'flag' ? '' : 'flag';

        // Process the remaining mines // if (this.squares[obj.pos[0]][obj.pos[1]].type == 'mine') {
        // this.allRight = true;
        // } else {
        // this.allRight = false;
        // }
        if (obj.className == 'flag') {
            this.mineNumDom.innerHTML = --this.surplusMine;
        } else {
            this.mineNumDom.innerHTML = ++this.surplusMine;
        }

        if (this.surplusMine == 0) {
            for (var i = 0; i < this.tr; i++) {
                for (var j = 0; j < this.td; j++) {
                    if (this.tds[i][j].className == 'flag') {
                        if (this.squares[i][j].type != 'mine') {
                            this.gameOver();
                            return;
                        }
                    }
                }
            }
            alert("Congratulations on your successful minesweeping!");
            this.init();
        }
    }

};

// Game over method gameover
Mine.prototype.gameOver = function (clickTd) {
    // 1. Display all mines // 2. Cancel the click event of all grids // 3. Mark the clicked mines in red for (var i = 0; i < this.tr; i++) {
        for (var j = 0; j < this.td; j++) {
            if (this.squares[i][j].type == 'mine') {
                this.tds[i][j].className = 'mine';
            }
            this.tds[i][j].onmousedown = null;
        }
    }

    if (clickTd) {
        clickTd.className = 'redMine';
    }
};

//Button functionality var btns = document.querySelectorAll('.header button');
var mine = null;

var btnKey = 0; // Level index // Beginner, intermediate, advanced difficulty settings var headerArr = [
    [9, 9, 10], [16, 16, 40], [28, 28, 99]
];

for (let i = 0; i < btns.length - 1; i++) {
    btns[i].onclick = function () {

        // Clear the previously clicked style btns[btnKey].className = '';
        this.className = 'active';

        mine = new Mine(...headerArr[i]);
        mine.init();

        // Update status btnKey = i;
    }
}

// The page starts with the primary minesweeper btns[0].onclick();
btns[3].onclick = function () {
    mine.init();
}

Source code

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • Share your own minesweeper game made with JS
  • Using pure javascript to implement the classic minesweeper game
  • HTML+JavaScript to implement the minesweeper game
  • javascript minesweeper game
  • JavaScript version of the classic game Minesweeper game complete example [with demo source code download]
  • JavaScript makes Windows classic minesweeper game
  • js+canvas implements a simple minesweeper game
  • Implementing a minesweeper game code example using javascript
  • Teach you step by step to create a minesweeper game using JavaScript

<<:  How to use MySQL 5.7 temporary tablespace to avoid pitfalls

>>:  How to set directory whitelist and IP whitelist in nginx

Recommend

Native JS to achieve sliding button effect

The specific code of the sliding button made with...

CSS3 to achieve timeline effects

Recently, when I turned on my computer, I saw tha...

MySQL changes the default engine and character set details

Table of contents 1. Database Engine 1.1 View dat...

How to use less in WeChat applet (optimal method)

Preface I am used to writing less/sass, but now I...

Installation and configuration tutorial of MongoDB under Linux

MongoDB Installation Choose to install using Yum ...

Introduction to TypeScript interfaces

Table of contents 1. Interface definition 2. Attr...

Introduction to MySQL role functions

Table of contents Preface: 1. Introduction to rol...

Detailed explanation of CSS style sheets and format layout

Style Sheets CSS (Cascading Style Sheets) is used...

Detailed installation process of mysql5.7.21 under win10

This article shares the installation of MySQL 5.7...

8 JS reduce usage examples and reduce operation methods

reduce method is an array iteration method. Unlik...

Implementation of CSS scroll bar style settings

webkit scrollbar style reset 1. The scrollbar con...

Design Theory: Textual Expression and Usability

<br />In text design, we usually focus on th...

Detailed explanation of MySQL cumulative calculation implementation method

Table of contents Preface Demand Analysis Mysql u...