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

Do you know how to optimize loading web fonts?

Just as the title! The commonly used font-family l...

JavaScript to show and hide the drop-down menu

This article shares the specific code for JavaScr...

Django2.* + Mysql5.7 development environment integration tutorial diagram

environment: MAC_OS 10.12 Python 3.6 mysql 5.7.25...

Markup Language - Anchor

Previous: Markup Language - Phrase Elements Origin...

Vue implements an example of pulling down and scrolling to load data

Table of contents Step 1: Installation Step 2: Ci...

Example analysis of the usage of the new json field type in mysql5.7

This article uses an example to illustrate the us...

Alibaba Cloud Server Domain Name Resolution Steps (Tutorial for Beginners)

For novices who have just started to build a webs...

Why should MySQL fields use NOT NULL?

I recently joined a new company and found some mi...

CSS 3.0 text hover jump special effects code

Here is a text hovering and jumping effect implem...

Detailed explanation of this reference in React

Table of contents cause: go through: 1. Construct...

Tutorial on installing mysql5.7.17 via yum on redhat7

The RHEL/CentOS series of Linux operating systems...

Solution to installing vim in docker container

Table of contents The beginning of the story Inst...

Writing a web calculator using javascript

This article mainly records the effect of using j...

Detailed explanation of samba + OPENldap to build a file sharing server

Here I use samba (file sharing service) v4.9.1 + ...