Search code examples
javaminesweeper

Java Minesweeper - ArrayIndexOutOfBounds Exception


I am new to Java programming and would like to seek your help. I'm trying to develop a simple minesweeper game using Java. However, I keep getting the error "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1 at practice.week.pkg4.PracticeWeek4.main(PracticeWeek4.java:55)"

This occurs when I'm trying to place digits around the square which has a bomb. I understand that perhaps the 1 has went out of the array, causing the exception to occur. However, I'm not sure how to go about catching the error. Would appreciate any kind help.

Eg: Sample Output

1 1 1

1 B 1

1 1 1

Here is my code snippet:

public static void main(String[] args) {
        // TODO code application logic here
        int rows = 9;
        int cols = 9;
        char[][] map = new char[rows][cols];
        int count = 0;


        for(int i = 0; i<map.length; i++)
        {
            for(int j = 0; j<map[i].length; j++)
            {
                map[i][j] = '.';
            }
        }

        Random rnd = new Random();
        do
        {
            int x = rnd.nextInt(rows);
            int y = rnd.nextInt(cols);

            for(int i = 0; i<map.length; i++)
            {
                for(int j = 0; j<map[i].length; j++)
                {


if(map[x][y] != 'B' && x > 0 & y > 0)
                { 
                    map[x][y] = 'B';
                    map[x-1][y-1] = '1'; 
                    map[x-1][y] = '1';
                    map[x-1][y+1] = '1';
                    map[x][y-1] = '1';
                    map[x][y+1] = '1';
                    map[x+1][y-1] = '1';
                    map[x+1][y] = '1';
                    map[x+1][y+1] = '1';
                    count++; 
                }

                }   

            }
        }
        while(count < 10);


        for(int x = 0; x<map.length; x++)
        {
            for(int y = 0; y <map[x].length; y++)
            {

            }
        }

        for(int x = 0; x<map.length; x++)
        {
            for(int y = 0; y<map[x].length; y++)
            {
                System.out.print(map[x][y] + " ");
            }
            System.out.println("");
        }



    }

Solution

  • The do-while loop for setting the mines is on the right track, but the way you are updating the counts for surrounding blocks is causing the IndexOutOfBoundsException. And these two loops

    for(int i = 0; i < map.length; i++)
    {
        for(int j = 0; j < map[i].length; j++)
    

    serve no purpose. You need to rearrange it to handle multiple mines, etc, so why not set all the mines first:

    do
    {
        int x = rnd.nextInt(rows);
        int y = rnd.nextInt(cols);
        if (map[x][y] != 'B')
        {
            map[x][y] = 'B';
            count++;
        }
    } while(count < 10);
    

    Then go through the map, and count the number of mines surrounding each block:

    for (int x = 0; x < map.length; x++)
    {
        for (int y = 0; y < map[x].length; y++)
        {
            if (map[x][y] == 'B')
                continue;
    
            // Count the number of mines around map[x][y]
            int mines = 0;
            for (int xOffset = -1; xOffset <= 1; xOffset++)
            {
                // This is an important step - without it, we will access elements off the edge of the map
                if (x + xOffset < 0 || x + xOffset >= map.length)
                    continue;
    
                for (int yOffset = -1; yOffset <= 1; yOffset++)
                {
                    // Another check for the edge of the map
                    if (y + yOffset < 0 || y + yOffset >= map[x].length)
                        continue;
    
                    if (map[x + xOffset][y + yOffset] == 'B')
                        mines++;
                }
            }
    
            map[x][y] = "012345678".charAt(mines); // Get the number as a character
        }
    }