-2

I am trying to make MineSweeper for a project and I am stuck on a certain part. the explode method below works fine but It seems that I cannot call the method within the method. Without posting all the code, I wanted to see if anyone knew if this is a known illegal thing in Java and/or how to bypass it.

public void explode(int row, int col) {
    if(board[row][col].mCount==0 && !board[row][col].isMine()) {
        for (int r = row - 1; r <= row + 1; r++) {
            for (int c = col - 1; c <= col + 1; c++)                        
            if ((r >= 0 && r < user.userRow) && (c >= 0 && c < user.userCol)) {
                board[r][c].setExposed(true);
                if(board[r][c].mCount == 0) {
                    explode(r,c); // <======= PROBLEM LINE
                }
            }
        }
    }
}

It is not giving me a compilation error, but it throws an error when I run the game.

Noob4sure
  • 1
  • 5
  • Could you explain what error you're getting? Maybe post a stacktrace? – PakkuDon Jan 26 '14 at 01:11
  • 8
    `explode2 != explode`. You are not calling the same method. You should post `explode2` method too, as well as the [stack trace](http://en.wikipedia.org/wiki/Stack_trace). – Christian Tapia Jan 26 '14 at 01:11
  • 2
    You can have a method call itself, this is called recursion. You should make sure that there is some case where the method will stop calling itself though, or you will get a stack overflow. – Jems Jan 26 '14 at 01:12
  • Oh sorry I forgot to change that to explode(r,c). I am using explode2, which is a different method that does the same thing. This is how get around that error, by using a method with a different name with identical code, which then feeds it into explode3. When I try to use just explode(r,c) withing explode(), I get the following errors:`Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError at mini.Cell.isMine(Cell.java:26) at mini.MineSweeperGame.explode(MineSweeperGame.java:92) at mini.MineSweeperGame.explode(MineSweeperGame.java:101)` – Noob4sure Jan 26 '14 at 01:22
  • 3
    Please post the entire exception as an edit. – Elliott Frisch Jan 26 '14 at 01:27

1 Answers1

0

I think I see what's going on. You have your neighbors loops and those I think are correct except you are not excluding the "current" index. That is, in the inner loop, when r == row and c == col the method calls itself with the same indexes.

Another thing is that subsequent calls will "loop back" and check the previous indexes. For example if you are checking row == 6, col == 7, moving on to row == 6 + 1, col == 7 + 1 will then check row == 7 - 1, col == 8 - 1. This might be solved by just checking if the grid position has been already revealed.

public void explode(int row, int col) {
    if (board[row][col].mCount==0 && !board[row][col].isMine()) {
        for (int r = row - 1; r <= row + 1; r++) {
            for (int c = col - 1; c <= col + 1; c++) {

                if (c == col && r == row) { // make sure it's
                    continue;               // not the current index
                }

                if ((r >= 0 && r < user.userRow)
                        && (c >= 0 && c < user.userCol)
                        && (!board[r][c].isExposed())) { // check if
                                                         // already shown
                    board[r][c].setExposed(true);

                    if(board[r][c].mCount == 0) {
                        explode(r,c);
                    }
                }
            }
        }
    }
}

You could probably do to refactor that so the logic is more clear but anyhow I think that's the cause of the exception.

Also just as a side note, you have this syntax here where the for loop is not a block:

for(/* ... ... ... */)
if(/* ... ... ... */) {

}

That's probably something you can do without. When you have some code that can potentially crash the program you should keep your syntax as clear and conventional as possible.

Radiodef
  • 37,180
  • 14
  • 90
  • 125
  • I tried something similar right before I read this post. This is what I did, as well as your suggestion, without any luck :/. `public void explode(int row, int col){ if(board[row][col].mCount==0 && !board[row][col].isMine()) { for (int r = row - 1; r <= row + 1; r++) for (int c = col - 1; c <= col + 1; c++){ if ((r >= 0 && r < user.userRow) && (c >= 0 && c < user.userCol)) { board[r][c].setExposed(true); if(board[r][c].mCount == 0 && (board[r][c] != board[row][col])) { explode(r, c); } } } } }` But I think you are on the right track, it is going into an infinite loop. – Noob4sure Jan 26 '14 at 02:23
  • Yeah, actually, you're right, it won't be enough. Because when you make a subsequent call to `explode`, it will check the neighbor's neighbors: which include the previous index. For example say you have some indexes `6, 7`, you move on to `6 + 1, 7 + 1` but that call will check `7 - 1, 8 - 1`. You need to work on your logic so it only propagates outwards instead of "looping back". – Radiodef Jan 26 '14 at 02:42
  • It occurred to me you could try just checking if the coordinates are already revealed. I think that should do the trick. That should ensure your recursion always moves outwards. – Radiodef Jan 26 '14 at 03:11
  • Yea you are right, it would just loop forever by going back to the previous coordinates. I added one more condition in the if statement and it took care of it. You da man! I appreciate it. – Noob4sure Jan 26 '14 at 16:24