NullPointerException in sweeping program

So, I am a computer science student and a young Java programmer. Someone asked me to help them in a task where they need to create a fairly basic minesweeper program. This program does not use mines with a mark at all, but, in addition, it is functionally the same as any other sweeping game.

I am throwing a NullPointerException when I try to run a program. I researched what this could mean, and now I know that it really should be a NoObjectException or DereferenceException, but I'm still not closer to solving the problem.

This exception occurs when the makeField method of the Tile class is called. Also, I'm really trying to bow my head to the correct inheritance, static or non-static, public vs. private and how all these relationships are interconnected, so I'm sorry if this is a general noob question.

So, I have a main file, a class superclass and two subclasses of the tile class - Bomb and Flat. A bomb is a tile with a bomb in it, and Flat is any tile that is not a bomb.

public class MineSweeperMain{ public static void main(String[] args) { Scanner kybd = new Scanner(System.in); int dimension; Tile[][] gameBoard; System.out.print("Enter the dimension of the board you would like to play on:\t"); dimension = kybd.nextInt(); gameBoard = Tile.makeField(dimension); Tile.printField(gameBoard, dimension); } } 

//

 public class Tile { static Random rand = new Random(); boolean isBomb; boolean isRevealed; int posX, posY; int noOfAdjacentMines; public Tile() { isRevealed = false; } public static int detectMines(Tile[][] board, int dimensions) { int detectedMines = 0; for(int i = 0; i < dimensions; i++) { for(int j = 0; j < dimensions; j++) { if(board[i][j].isBomb) detectedMines++; } } return detectedMines; } public static Tile[][] makeField(int dimensions) { int rowOfMines = dimensions / 3; int randomInRow; Tile[][] Board = new Tile[dimensions][dimensions]; for(int i = 0; i < dimensions; i++) for(int j = 0; j <= rowOfMines; j++) { randomInRow = rand.nextInt(dimensions); Board[i][randomInRow] = new Bomb(); } for(int i = 0; i < dimensions; i++) for(int j = 0; j < dimensions; j++) { if(!Board[i][j].isBomb) Board[i][j] = new Flat(); } return Board; } public static void printField(Tile[][] board, int dimensions) { for(int i = 0; i <= dimensions; i++) { for (int j = 0; j <= dimensions; j++) { if(i ==0) System.out.print(i + " "); else if(j == 0) System.out.print(j + " "); else { if(board[i-1][j-1].isRevealed && !board[i-1][j-1].isBomb) System.out.print(board[i-1][j-1].noOfAdjacentMines + " "); else System.out.print("# "); } } } } } 

//

 public class Flat extends Tile{ public Flat() { noOfAdjacentMines = 0; isBomb = false; isRevealed = false; } } 

//

 public class Bomb extends Tile{ public Bomb() { isBomb = true; isRevealed = false; } } 

//

+4
source share
6 answers

Your problem is in the second loop of the makeField method, which I think.

When you check if(!Board[i][j].isBomb) This particular value will be null because you have not filled your array yet. There are a couple of random bombs placed in the first cycle, but the rest of the values โ€‹โ€‹are zero.

I would recommend reversing your loops. First swipe everything around and make the whole board out of Flat without checking anything.

Then in the second loop, you just overwrite the Flat pair with Bomb s

Another solution is to make this tiny modification and check for null:

if(null == Board[i][j] || !Board[i][j].isBomb)

Please note that if you make this decision, the zero check should be FIRST . This is due to something called short-circuting .

The reason I recommend my first solution, although switching loops, is that it eliminates 1 extra comparison, not a huge deal, but you never know ...

+6
source

There are many questions here, but to answer the main question why you get a null pointer:

 Board[i][randomInRow] = new Bomb(); 

In the above code, you randomly place bombs around the board in each row. Note that this will only set the value for the subset of squares.

Then you go through EVERY square and do the following:

 if(!Board[i][j].isBomb) Board[i][j] = new Flat(); 

The problem is that if a square was not assigned by a bomb, nothing was assigned to it, therefore it is equal to zero. When you call isBomb on what is null, you get a null pointer. This test should be checked if Board[i][j] == null .

With this, you can start less than that. Although I find it relatively basic how games go, I think you need a more basic understanding of Java before diving into something like this.

+5
source

I think I see a problem. When you make a board, you set bombs on random elements in a row. Then you check them all to see if there is a bomb there.

 if(!Board[i][j].isBomb) // What if board[i][j] is not set? Null Pointer Exception Board[i][j] = new Flat(); 

This is useful?

+5
source

The problem is that you are not populating your Bomb array.

You will need something like this:

  for(int i = 0; i < dimensions; i++) for(int j = 0; j < dimensions; j++){ Board[i][j] = new Tile(); // or something if(!Board[i][j].isBomb()) // use an accessor Board[i][j] = new Flat(); } return Board; } 
0
source

The problem is that the board is not initialized by the default plate.

You have:

 Tile[][] Board = new Tile[dimensions][dimensions]; 

and then you randomly assign bombs:

 Board[i][randomInRow] = new Bomb(); 

Tiles that were not bombs are still null. So calling this will result in NPE (NullPointerException):

 if (!Board[i][j].isBomb) 

To solve this variable, run the following line:

 if (!Board[i][j] == null) 

So, if the board in this current position is zero, it was not initialized as a bomb.
There are other ways you could rotate and flip the code to solve this problem, but this is the easiest I was thinking about.

0
source

When you declare your multidimensional array, you are not getting any objects created in your arrays. You need something like

 for(int i = 0; i < dimensions; i++) { for(int j = 0; j < dimensions; j++) { Board[i][j] = new Tile(); } } 
-one
source

Source: https://habr.com/ru/post/1395498/


All Articles