“This is the 29th day of my participation in the Gwen Challenge in November. See details of the event: The Last Gwen Challenge in 2021”

1. De-mining needs analysis

  1. Initialization part
  2. Diffusion algorithm (DFS search)
  3. Left and right mouse button event processing part
  4. The game’s successes and failures
  5. Game progression (start, end, pause, continue, etc.)

2. Initialize the part

  1. Initializing basic data (initDefault)

Initializes the number of lightning, the number of lightning disk rows and columns, the array of lightning coordinate storage, the number of identifier storage, the total number of cells, time, the number of identifier lightning, the width/height of lightning disk, display time, and the initial style of the remaining number of lightning

// Initialize some default values
function initDefault () {
    landmineCon.style.width = rowNum * 20 + rowNum + 1 + 'px';
    landmineCon.style.width = colNum * 20  + colNum + 1 +'px';
    time.children[0].innerHTML = ' ';
    time.children[1].innerHTML = ' ';
    mineCount.innerHTML = mineNum;
    mineXPos = [];
    mineYPos = [];
    identifyMinePosX = [];
    identifyMinePosY = [];
    mineIdentifyCount = 0;
    gameTime = 0;
    grids = colNum * rowNum;
    isStarted = false;
}
Copy the code
  1. RandomMinePos coordinates of randomly generated thunder

The main difficulty here is how to ensure that the generated thunder is different. The method I used here is to convert the coordinates x and y of the thunder into ‘xy’ and store them in an ARR array. Each time a random thunder is generated, arr.indexof (‘xy’) is called to check if it is present.

// Randomly generate the location of thunder
function randomMinePos () {
    var arr = [];
    for (var i = 0; i<mineNum; i++){
            var x = Math.floor(Math.random()*rowNum),
                    y = Math.floor(Math.random()*colNum);
            while (arr.indexOf(' '+x+y) ! = = -1) {
                    x = Math.floor(Math.random()*rowNum);
                    y = Math.floor(Math.random()*colNum);
            }
            arr.push(' '+x+y); mineXPos.push(x); mineYPos.push(y); }}Copy the code
  1. Dynamically Initializing ul(initLi)

Because the game has three difficulties, each difficulty has a different size of lightning disk, so after each difficulty selection, a new lightning disk needs to be generated.

However, due to the influence of considering reflow: – Use the DocumentFragment to insert once – if the current Li number is smaller than the required Li number, it will be generated on the basis – If the current Li number is smaller than the required Li number, it will be directly deleted and added again

// Insert li dynamically
function initLi () {
    var len = mineGrid.length,
            grids = colNum * rowNum;

    if (len < grids) {
            var fragment = createFragment();
            for (var i = 0; i<grids - len; i++) {
                    var li = createLi();
                    fragment.appendChild(li);
            }
            mineUl.appendChild(fragment);
    }else if (len > grids) {
            mineUl.innerHTML = ' ';
            var fragment = createFragment();
            for (var i = 0; i<grids; i++) {
                    varli = createLi(); fragment.appendChild(li); } mineUl.appendChild(fragment); }}Copy the code
  1. Initialize mineMap and visited arrays (initMineMap)
  • The initialized mineMap array is 0
  • MapIsVis is set to false to indicate that it has not been traversed
  • First, assign the mines to the mineMap array (mines are represented by “#”).
// Generate a lightning disk
function initMineMap () {
    // Initialize the lightning disk
    for (var i = 0; i<rowNum; i++) {
            mineMap[i] = new Array(colNum);
            mapIsVis[i] = new Array(colNum);
            for (var j = 0; j<colNum; j++){
                    mineMap[i][j] = 0; // Start grid all initialized to 0
                    mapIsVis[i][j] = false;// None of them are accessed at first
                    mineGrid[reaerchIndexId(i, j)].innerHTML = ' ';
                    mineGrid[reaerchIndexId(i, j)].style.backgroundColor = 'RGB (192192192).; }}// Add mines
    for (var i = 0; i<mineNum; i++){
            mineMap[mineXPos[i]][mineYPos[i]] = The '#';//# stands for landmine}}Copy the code
  1. Compute the mineMap array (calcMineMap): Compute the mineMap array
/ / mineMap calculation
function calcMineMap() {
    // Count the number of mines near each grid
    for (var i = 0; i<mineNum; i++) {
            for (var j = 0; j<8; j++){
                    rx = mineXPos[i] + xx[j];
                    ry = mineYPos[i] + yy[j];
                    if (rx < 0 || rx >= rowNum || ry < 0 || ry >= colNum || mineMap[rx][ry] === The '#') {
                            continue; 
                    }else{ mineMap[rx][ry] ++; }}}}Copy the code
  1. Bind events for elements (initAddEvent)
// Bind events
function initAddEvent() {
    mineUl.addEventListener('click', mineGame, false);
    mineUl.addEventListener('contextmenu', identify, false);
    newgame.addEventListener('click', newGame, false);
    continueBtn.addEventListener('click', continueGame, false);
    pause.addEventListener('click', startOrPause, false);
}
Copy the code

3. Diffusion Algorithm (DFS)

Deep search (essentially a recursion)

MapIsVis = true; If you need to pay attention to backtracking later

4. Left and right mouse button event processing part

  1. Left mouse click (mineGame)
  • If mineMap is 0, DFS
  • If mineMap is # gameOver
  • If mineMap>0, just display it
  1. Click 🚩 once with the right mouse button

When the number of flags reaches mineNum, a check is made. If all flags are correct, gameSuccess(); Use model prompts if there are errors.

  • Click on ❓ twice
  • Three clicks to cancel

Since the number of remaining mines is related to the number of flags, care should be taken to correct the current total number of flags and the number of remaining mines each time the style is adapted from flags to other values

5. The game’s successes and failures

  1. GameSuccess (gameSuccess)

There are two ways to win:

  • The ray is all identified (testIdentify)
  • Only Ray has not been clicked (more info info)
  1. Game failure (gameOver)

When clicked to the position mineMap is #

6. Game progression

  1. Start the game (startOrPause)

When the smiley face is clicked, the game begins.

Implementation principle: set a lock to the left and right mouse key event handler function, after the smiley face click after it is opened.

  1. Game Pause
  2. Continue the game
  3. Start the game again (newGame)
  4. Return to main Menu

Because of timing problems, you should be careful to clear and re-establish timers

💘 previous excellent articles

  • Cow guest latest front-end JS written test 100 questions
  • The latest front end of the interview questions summary (including analysis)
  • CSS to achieve a free flying bird 🐦
  • Grab the latest front end test five hundred data analysis JS interview hot spots
  • Happy cat stroking for VSCode and website adoptive cats
  • Native JavaScript soul Test (1), how much can you answer?
  • A thorough understanding of prototypes and prototype chains in JavaScript
  • Complete understanding of EventLoop in JavaScript
  • “2W word big chapter 38 interview questions” completely clear JS this pointing to the problem
  • IO/Aaronchuo /p…

After 💥 language

Guys, if you find this article helpful, give a like to 👍 or follow ➕ to support me.

In addition, if this article has a question, or do not understand part of the article, you can reply to me in the comment section, we come to discuss, learn together, progress together!

If you feel that the comment section does not understand, you can also add my wechat (li444186976) or QQ (3315161861) for detailed communication, the name is battlefield small bag.