Commented and explained code of Minesweeper game in Java



We will now explain in detail how to do, and understand all program logic of a minesweeper game in the Java programming language.

The game code is on our last article of our online course Java:
Game: How to make a Minesweeper in Java





We split the game into three classes, the 'MineSweeper' which simply contains the main method and creates an object of type 'Game', we have a class of 'Game' which will manage all the logic and flow of the game and finally the class 'Board' that will generate the boards (mines and boardgame) and the methods that deal with the trays.



Minesweeper game in Java: the Board.java Class


This class is responsible for board and methods that involve.
In fact, we deal with two trays:


- int[][] mines

This board is initially populated with numbers '0 ', by the method 'startMines()'.

After that, we'll randomly select 10 locations to place the mines, using the method 'randomMines()'. In places where there are mines, we put the integer number '-1'.
This method draws two integers between 1 and 8, using the Random class. Let's do it with a while loop, that each iteration will check if that position is already drawn the number '-1'. If that location has already been drawn, the Boolean 'raffled' will be true and looping will repeat until we have 10 different locations with the number '-1'.

After that, we fill the tips, ie we put in each block of the board the number of mines that exist around.
So if a board position has the number '2 'is because there are two mines around that block.
We do this by counting how many bombs there are only around each block.
We create, in fact, a 10x10 matrix, where lines 0 and 9 and rows 0 and 9 won't be used. Why ?

For that to calculate how many bombs are in the neighborhood, we contain just how many bombs there are in 8 locations around. This is necessary because if we used a 8x8 board, the houses of the border would not have 8 neighbors.

To check the pumps around, we use two loops:

for(int i=-1 ; i<=1 ; i++)
    for(int j=-1 ; j<=1 ; j++)


If you want to check how many bombs there around the block: mines [row] [column], we put into these ties:
mines[row+i][column+j]
These two ties will go the 8 locations around the block mines[line][column].
However, we will only check the surroundings if the site in question does not have a mine:
if (mines [line] [column] != -1)

After checked it, check to see if mine is in position around, and if so, increment the local board 'mine', because it also receives the number of mines around:
if (mines [line+i] [column + j] == -1)
     mines[line] [column]++;

Ready. Now we have a 10x10 board, but we will use only the 8x8 board and this 'internal' board have 10 mines and all the blocks that are not mine store how many mines are around you.




- char[][] boardgame
It is a board of characters, initially charged with underscore '_' in the method 'startBoard()', this means that this field has not yet been chosen.
We still have the method 'show()', which simply displays this whole tray of characters in a formatted way.

Method 'showMines()' puts an asterisk '*' in all places where there are mines. This method serves to show where mines exist and will be triggered when the player loses the match.

Making a move:
The move is made by the method 'setPosition()', which returns 'true' if you lose (ie if there is a mine where you played) and 'false', if there is not a mine in the location you chose.
We should make this method very robust, making sure that the player does not come with numbers out of hope (ie, greater than 8 or less than 1):
( Line < 1 || Line > 8 || Column < 1 || Column > 8)

And check whether the place he has played has already been chosen before.
(boardgame[Line][Column] != '_')

Still in method 'setPosition()', use the method 'getPosition()', which returns what exists in the block when we pass the row and column. If there is '-1' is because there is mine, returns 'true' and the game ends. If there is any other number, the method returns 'false' and the game does not end.

After playing we checked if the player won by the method has 'win()' which simply counts how many blocks have not been displayed, that is, how underlines exist. If there are only 10, it is because the blocks that remained were precisely those containing mines, the method returns 'true' and the player wins. If you have more than 10, because it is not yet complete and returns false.

Another important method, and perhaps most difficult, is the 'openNeighbors()', which will check all the neighboring houses of the board of mines, except if these territories are located on lines 9 or 0, or 0 or 9 columns. During the check, we check if the neighbor has a mine, and if we do not have this house show on the board of characters:
for (int i = -1; i <2; i + +)
    for (int j = -1, j <2 j + +)
 if ((mines [i + row] [column + j]! = -1) && (line! = 0 && line! = 9 && column! = 0 && column! = 9))
    board [row + i] [column + j] = Character.forDigit (mines [i + row] [column + j], 10);
 
Note that we use the method 'Character.forDigit (int num, int base)', receiving an integer representing a number and its base.
What this method does is take a number and transform into character. In our case, the numbers are in decimal base (hence the 10) and these numbers are nothing more than the mines[][] board. That is, we are putting numbers on the board of characters.



Minesweeper game in Java: the Game.java Class


This class starts with the default constructor creating a board, the 'board' and calls the method that will control the game, the 'Play', which receives the object 'board', type "Board".

The game, as usual, is controlled by a do while loop that ends only when the boolean 'finish' is true.
This only becomes Boolean true if the method 'setPosition()' returns true, saying it found a mine, or when the method has 'win()' returns true, saying that the player has won, because there were only 10 blocks in the game .

We use the integer 'turn', which will count how many rounds the game has had.
The move is made in:
finish = board.setPosition();

If we have not hit a mine:
if (!finish)

Let's open the blocks that block neighbors who chose the 'setPosition()' to see the tips, this occurs:
board.openNeighbors(); 

After open neighboring houses can be that the player has won, do it by checking:
finish = board.win();

As the game ends, or when the application out of the while loop, we will show the message of congratulations or loss.

When the method 'win()' has returns true because the player is won, then we display a message of congratulations as well as how many rounds he won:
if (board.win() ) { 
   System.out.println ("Congratulations, you let the 10 fields with the mines in " + round + " rounds"); 
   board.showMines(); 


Now is not the conditional returns true if the else is going to be the case that he has lost. Then we say that he had lost and show where mines are located by method 'showMines()'.

3 comments:

Anonymous said...

Why is the mine area just limited to the 8x8 area? And if it's outside that area, would it cause an error?

Unknown said...

An online multiplayer mode was definitely true on my TODO list for this game. Infact, I was more into MSN on the flags for a while, but hated that it was still offline, and thus began this project.
how to play minesweeper like a pro

Sharina said...

I compiled this code and it won't run. I added void to Jogo and that allowed it to compile but then when you run MineSweeper it doesn't do anything. Can you please let me know what to do to make this game run?