6

I am trying to make minesweeper in JavaScript and I have run into a problem that has had me stuck for days. I am aware there are already posts about this topic however I've read them and tried it out and I've had no luck.

The problem I am having is when the user presses a blank square I want it to discover every blank square touching it (Blank square meaning a square on the grid that has 0 mines 1 square to the side or diagonal to it).

The program now clears almost every blank square that are one square apart however it is still missing a few random ones and I can't quite figure out why.

I have tried adding other combinations when calling runOffset() such as runOffset(25, 25) and runOffset(-25, -25) however this didn’t change anything. Is it a simple fix, or have I gone about this wrong?

Example2

The circled squares are squares that should have been cleared but weren't and the X is where the user clicked.

• Am I writing this out wrong? (Will the way I’ve written out the function do what I want it to do?)

• Is the function checkBlanks() being returned for the wrong reason or something?

• What am I missing for it to miss the squares circled in the image above?

Full Code (Line 297)

function borderingBombs(safeSquareCoords) {
    var minesNext = 0;
    for (var i = 0; i < mines.length; i++) {
        var mineCoords = mines[i].split(",");
        if (mineCoords[0] - 25 == safeSquareCoords[0]) {
            if (mineCoords[1] == safeSquareCoords[1]) {
                // Left
                minesNext++;
            } else if (mineCoords[1] - 25 == safeSquareCoords[1]) {
                // Top Left
                minesNext++;
            } else if (mineCoords[1] == safeSquareCoords[1] - 25) {
                // Bottom Left
                minesNext++;
            }
        } else if (safeSquareCoords[0] - 25 == mineCoords[0]) {
            if (mineCoords[1] == safeSquareCoords[1]) {
                // Right
                minesNext++;
            } else if (mineCoords[1] - 25 == safeSquareCoords[1]) {
                // Right Top
                minesNext++;
            } else if (mineCoords[1] == safeSquareCoords[1] - 25) {
                // Bottom Right
                minesNext++;
            }
        } else if (mineCoords[1] - 25 == safeSquareCoords[1] && mineCoords[0] == safeSquareCoords[0]) {
            // Bottom
            minesNext++;
        } else if (safeSquareCoords[1] - 25 == mineCoords[1] && mineCoords[0] == safeSquareCoords[0]) {
            // Top
            minesNext++;
        }
    }
    return minesNext;
}

// Discover all blanks touching blanks
function checkBlanks(blnkSquare) {
    if (!discovered(blnkSquare)) {
        var blnkSquareCoords = blnkSquare.split(",");
        safe.push(blnkSquare);
        ctx.drawImage(blankImg, blnkSquareCoords[0], blnkSquareCoords[1]);
        if (borderingBombs(blnkSquare) == 0) {
            runOffset(blnkSquareCoords, 0, -25); // Top
            runOffset(blnkSquareCoords, 0, 25); // Bottom
            runOffset(blnkSquareCoords, 25, 0); // Right
            runOffset(blnkSquareCoords, -25, 0); // Left
            runOffset(blnkSquareCoords, -25, 25);
            runOffset(blnkSquareCoords, 25, -25);
        }
    }
}

function runOffset(origin, xOffset, yOffset) {
    var newBlnkSquare = origin;
    newBlnkSquare[0] = parseInt(newBlnkSquare[0])+xOffset;
    newBlnkSquare[1] = parseInt(newBlnkSquare[1])+yOffset;
    outBlnkSquare = newBlnkSquare[0] + "," + newBlnkSquare[1];
    if (newBlnkSquare[0] >= 0 && newBlnkSquare[1] >= 0 && newBlnkSquare[0] < 250 && newBlnkSquare[1] < 250) {
        if (!isMine(outBlnkSquare)) {
            drawSafe(outBlnkSquare);
        }
    }
}
Tooble
  • 81
  • 7
  • 1
    I took a short look at your code and it seems that the drawSafe function at line 239 and the checkBlanks function at line 305 keep on calling each other. – Dennisvdh Jun 27 '18 at 14:49
  • That's the idea it's meant to, it checks the one selected by the user then it offsets it by one square and checks that one but for every square around the one the user set and then all the ones around that. Unless I'm thinking about this wrong? – Tooble Jun 27 '18 at 14:53
  • Please add a clear, concise definition of "every blank square touching it", what constitutes your adjacency model here?. That then becomes the problem to resolve. – Mark Schultheiss Jun 27 '18 at 15:35
  • Clarify "starring" as in "blank square it stared on" – Mark Schultheiss Jun 27 '18 at 15:37
  • Edited - Sorry for not being clear – Tooble Jun 27 '18 at 15:55
  • Note, it might be good to paste your code in a js validator such as http://jshint.com/ or some such – Mark Schultheiss Jun 27 '18 at 16:01
  • SO now what is "has 0 mines adjacent" - just the sides, the corners etc. Not trying to be contrite here, but in the coding world precision means no ambiguity to the specifications and no assumptions to the problem domain - assume the reader has no idea what "minesweeper" is or does. "Close" for instance means something totally different with hand grenades, horseshoes and nuclear weapons than it does with cellular biology or accounting. – Mark Schultheiss Jun 27 '18 at 16:03
  • Edited again, I put my code through jshint.com and fixed a load of errors, thanks. I also changed my description instead of adjacent I put "0 mines 1 square to the side or diagonal to it". – Tooble Jun 27 '18 at 16:18

1 Answers1

3

Your issue here is that you're checking the diagonals. Don't do that. Just check vertical and horizontal.

This will prevent the pattern you're seeing. You will still get clearing behavior when there are large empty expanses. Squares that are diagonal to the clicked square will clear if the square that is adjacent to it and the clicked square is also clear.

Dancrumb
  • 26,597
  • 10
  • 74
  • 130
  • Thanks! This seemed to have helped however this is still only happening in one direction example: [image](https://i.imgur.com/adNBYLv.png) here is the code: [code](https://pastebin.com/PSn9U9x6) – Tooble Jun 27 '18 at 18:26
  • It would probably help if you could indicate where the mines are in these cases – Dancrumb Jun 27 '18 at 18:44
  • I seemed to have fixed this issue but now it's not doing diagonals when I want it to. (I fixed it by calling the runOffset() twice more like this: `runOffset(blnkSquareCoords, -25, 25); runOffset(blnkSquareCoords, 25, -25);` – Tooble Jun 27 '18 at 19:10