0

I am writing a simple minesweeper, but I can't find a way to reveal the adjacent tiles properly. If a tile is blank, it is revealed and then the algorithm reveals all adjacent blank tiles. However I would like to reveal a layer of non blank tiles as well, just like the real minesweeper.

Here is my code:

void revealAdjCells(Tile [][] t,int x, int y) {
        if (!checkBounds(x,y)) {                    
            return; // check for bounds
        }

           if ((t[x][y].getNeighbours() == 0) && (!t[x][y].getVisibleState())) { // NO neighbours and not revealed
               t[x][y].setVisibleState(true); // reveal tile

               revealAdjCells(t,x+1,y); // recursion, reveal adjacent tiles
               revealAdjCells(t,x-1,y);
               revealAdjCells(t,x,y-1);
               revealAdjCells(t,x,y+1);
            } 
           else 
           {
               return;
           }
        }

getNeighbours() returns the amount of bombs that surround a nearby tile (horizontal,vertical,diagonal) and getVisibleState() returns a boolean that indicates whether a tile has been revealed or not.

Things that I have tried:

1) Removing getVisibleState() from if condition (terrible idea, leads obviously to stack overflow).

2) Checking bounds (x-1,x+1,y+1,y-1) and then revealing the tiles accordingly (doesn't work, getVisibleState() won't let the statement execute, because the tile that is examined by the recursion is already revealed).

So... yeah... I am stuck and I can't find a solution. Any algorithmic help is appreciated.

John M.
  • 245
  • 1
  • 3
  • 13
  • 2
    1. Yes, check bounds, 2. Use recursion. 3. Make sure that your stopping condition is good -- else you'll have a stack overflow error. 4. Look at other Java MineSweeper programs posted on this site, such as [this one](https://stackoverflow.com/a/7016492/522444) which is pretty darn good, if you had to ask me – Hovercraft Full Of Eels Jun 06 '19 at 22:18
  • 1
    Shouldn't you be checking for the current tile cell's visible state at the beginning of this recursive call, and returning from the method if the current tile has already been revealed? Else, what is stopping this method from recursing for ever? – Hovercraft Full Of Eels Jun 06 '19 at 22:28
  • 1
    e.g., `if (!checkBounds(x,y) || t[x][y].getVisibleState()) { return; }` – Hovercraft Full Of Eels Jun 06 '19 at 22:29
  • Sure, that will indeed stop the recursion. However even without using the second statement in if(), it works, because of my second if. The problem emerges when i attempt to modify the code to reveal the adjacent tiles that can potentially contain a number (but not a bomb). Currently the algorithm reveals the blank tiles (they contain 0) properly, but this behaviour is not the correct one. All minesweepers show a layer of tiles that each one contains the amount of bombs it is surrounded by. This is the behaviour I am trying to replicate. – John M. Jun 06 '19 at 22:38
  • BTW the Minesweeper link is pretty good, but for some reason I cannot find the algorithm, only code for Swing GUI. Swing though is not really useful, as I would like to create the GUI in JavaFX. JavaFX is much prettier IMO and looks 10 times better than Swing. – John M. Jun 06 '19 at 22:40
  • 1
    The code in that link is mine, and it uses a Model-View-Controller structure, meaning that the model can be used (with just a few modifications) with *any* GUI library. The algorithm is found within the model, but is spread out since it uses property change support and listeners for call-backs. Run the code to see that it does exactly the behavior that you're looking for, it recursively exposes all the empty cells and the non-empty border cells. – Hovercraft Full Of Eels Jun 06 '19 at 22:45
  • Thanks, appreciate it. But I would like to implement my own algorithmic version first, I avoid copying pasting code like the plague. Nobody really learns how to code by copy pasting, unless they understand the code already. – John M. Jun 06 '19 at 22:48
  • 1
    I agree, but the algorithmic information is there to study – Hovercraft Full Of Eels Jun 06 '19 at 22:53
  • Um, yeah... I just managed to solve my problem. I created another boolean, called it isVisited, wrote new getters/setters and instead of checking in my recursion if a tile is visible, I check if it is visited. Anyway, works like a charm now, thank you for your time and effort. – John M. Jun 06 '19 at 23:04
  • 1
    I did too, answer posted. You're not revealing the edges – Hovercraft Full Of Eels Jun 06 '19 at 23:06
  • 1
    We look to have solved it at the same time, only you had the whole program to play with, and I only had a fragment – Hovercraft Full Of Eels Jun 06 '19 at 23:06
  • 1
    Not sure who down-voted your question, but I have up-voted it to nullify the down-vote – Hovercraft Full Of Eels Jun 06 '19 at 23:09

1 Answers1

1

Your code is close, but you're not revealing the tile if t[x][y].getNeighbours() != 0 and you should be doing this. Perhaps something like:

void revealAdjCells(Tile [][] t,int x, int y) {

    // if out of bounds **or** if already revealed, return
    if (!checkBounds(x,y) || t[x][y].getVisibleState()) {                    
        return;
    }


    t[x][y].setVisibleState(true); // reveal tile **here **

    // do recursion only if no neighbors
    if (t[x][y].getNeighbours() == 0) { 
        // t[x][y].setVisibleState(true); // not **here**

        revealAdjCells(t,x+1,y); 
        revealAdjCells(t,x-1,y);
        revealAdjCells(t,x,y-1);
        revealAdjCells(t,x,y+1);
    } else {
        return;
    }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Yup, THAT was what I was trying to do, check for getNeighbours() != 0, but I couldn't make it work. But I managed :). Thank you! – John M. Jun 06 '19 at 23:18