简体   繁体   中英

Java Minesweeper StackOverFlowError Recursion

I'm trying to make a console version of MineSweeper.

Despite my efforts at the moment I am unable to figure out the 'flood-fill' part of MineSweeper, where if the square selected's surrounding neighbors do not contain a bomb, we now have to check those adjacent squares to find an adjacent bomb.

The code below works in the case the selected square is adjacent to a bomb:

// checking the adjacent cells, I made -1 = to the bomb value, rest of the cells
// are default(0)
public void sweep(int r, int c) {

    if (r < 0 || r >= grid.length || c < 0 || c >= grid[0].length) 
        return;

    int minRow = 0, minCol = 0, maxRow = 0, maxCol = 0, neighborBomb = 0;


    // means if I clicked a bomb, end the program
    if (grid[r][c] == -1) {
        System.out.println("Your selection [" + r + ", " + c + "] contained a bomb. .\nGAME OVER");
        System.exit(0);
    }

    // Series of if/else to find the min & max row col size to avoid going out of
    // bounds
    if (r == 0)
        minRow = 0;
    else
        minRow = r - 1;

    if (r == grid.length - 1)
        maxRow = r;
    else
        maxRow = r + 1;

    if (c == 0)
        minCol = 0;

    else
        minCol = c - 1;

    if (c == grid[0].length - 1)
        maxCol = c;
    else
        maxCol = c + 1;
    //if the selected cell is 0 & has not been searched yet.
    if (grid[r][c] == 0 && recurseSearch[r][c] == false) {

        recurseSearch[r][c] = true;
        // search adjacent cells to see how many bombs surround the cell in question
        neighborBomb = 0;
        for (int row = minRow; row <= maxRow; row++) {

            for (int col = minCol; col <= maxCol; col++) {

                if (grid[row][col] == -1) {
                    neighborBomb++;
                }

            }
        }
    }
        // cell will now display how many bombs are adjacent
        if (neighborBomb > 0) {
            grid[r][c] = neighborBomb;
            return;
        }
        //HERE I WANT TO CHECK ALL ADJACENT SQUARES BUT IT WILL ONLY RUN
        //sweep(r+1, c) rather than all the surrounding squares
        else {
            sweep(r + 1, c);
            sweep(r - 1, c);
            sweep(r + 1, c + 1);
            sweep(r + 1, c - 1);
            sweep(r - 1, c + 1);
            sweep(r - 1, c - 1);
            sweep(r, c + 1);
            sweep(r, c - 1);
        }
}

grid[][] is my gameboard essentially, recurseSearch[][] is a boolean that will keep track if a cell has been searched already or not. The mess of if/else statements is me trying to not get any IndexOutOfBoundErrors. When I try to run and pick a cell that is not surrounded by a bomb I get

   Exception in thread "main" java.lang.StackOverflowError

and it repeats the lines which are

   sweep(r + 1, c);
   sweep(r - 1, c);

Any ideas/suggestions would be helpful on how to make my recursion actually check every neighbor cell of the original r,c selected!

You call your method recursively after your check

//if the selected cell is 0 & has not been searched yet.
if (grid[r][c] == 0 && recurseSearch[r][c] == false) {
    recurseSearch[r][c] = true;
   // ...
}

Therefore you repeat the recursion for already visited fields,

But the recursion should only occur within this if block.

Your idea to keep track if a cell is already processed with recurseSearch[][] is not bad, but you don't correctly interrupt the recursion.

Change the first expression to:

if (r < 0 || r >= grid.length || c < 0 || c >= grid[0].length || recurseSearch[r][c]) 
    return;
recurseSearch[r][c] = true;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM