Search code examples
javaandroidwindows2d-games

Android Minesweeper algorithm


I'm developing a game "Minesweeper" for Andoid on Java and I have a problem when opening the cells. How to make sure that I click on the cell opened adjacent empty cells? (How it is done in Miner for Windows). Introduction: I have an array which i receive from bluetooth socket stream. Array like this :

1 9 1 0
1 1 1 0
0 0 0 0
0 0 0 0

9-is a mine 0-is blank cell 1-nearest mines count

After that i calculate game field

array = Model.getGameField();
int size = array.length;
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
{
    ((TableRow) table.getChildAt(i)).getChildAt(j).setTag(array[i][j] + "");
}

OnClick function :

if (iWantToSetFlag == 0)
                {
                    tmpBtn = ((Button) v);
                    if (!(tmpBtn.getTag().equals("9")))
                    {
                        OpenButtons(tmpBtn.getId() / 10,     tmpBtn.getId() % 10);
                        recreateTable();
                    }
                    else
                        startLose();
            }
            else
            {
                if (((Button) v).getText().equals("M"))
                    ((Button) v).setText("");
                else
                    ((Button) v).setText("M");
            }

I have a function

    private void OpenButtons(int x, int y)
    {
        array[x][y] = -1;
                    for (int k = -1; k < 2; k++)
        {
            for (int k1 = 1; k1 >= -1; k1--)
            {
                    if (x + k >= 0 && x + k < array.length && y - k1 >= 0 && y - k1 < array[x + k].length)
                        if (array[x + k][y - k1] == 0)
                            OpenButtons(x + k, y - k1);
            }
        }

    }

which recursively open cells but i have a StackOverFlow error. Help please.


Solution

  • You should be calling your recursion with changed parameters:

    if (array[x + k][y - k1] == 0)
        OpenButtons(x + k, y - k1);
    

    And of course, as has been mentioned in the comments of the question, you should check for the array bounds yourself instead of just ignoring the exceptions:

    if (x + k >= 0 && x + k < array.length &&
        y - k1 >= 0 && y - k1 < array[x + k].length) { ...
    

    put before your other if-clause will only check fields which actually exist. Ridding you of your malicious empty try-catch.


    Since the recursive algorithm will still cause a StackOverflowException for large fields, an iterative algorithm might be better suited here.

    private void OpenButtons(int x, int y) {
        Queue<Point> toOpen = new LinkedBlockingQueue<>();
        toOpen.add(new Point(x, y));
        array[x][y] = -1;
        while (!toOpen.isEmpty()) {
            Point p = toOpen.poll();
            x = p.x;
            y = p.y;
            for (int k = -1; k < 2; k++) {
                for (int k1 = 1; k1 >= -1; k1--) {
                    if (x + k >= 0 && x + k < array.length && y - k1 >= 0
                            && y - k1 < array[x + k].length)
                        if (array[x + k][y - k1] == 0) {
                            array[x + k][y - k1] = -1;
                            toOpen.add(new Point(x + k, y - k1));
                        }
                }
            }
        }
    }