Minesweeper v1.0 in JavaFx 2.0 |
This week I tried my hands at developing Minesweeper game in JavaFx 2.0 and the snapshot of version 1.0 is shown above. If OS installed on your laptop or PC is Microsoft Windows , then chances are that you might have played this game before. For those who don't know about this game here is a quick introduction to the rules.
As shown in snapshot below, the game consist of grid of identical squares. Some of these squares contains mines which of course are unknown to the player.
Minesweeper game when it starts. |
But how do player know that particular square has hidden mine ? For this user has to click a square (sometimes randomly). Clicking a square reveals number of bombs in the adjacent square. This is explained in snapshots below.
In above case top left square was clicked. It reveals number of mines in adjacent squares. |
In above case squares are flagged for mines. |
In above screenshot player has correctly flagged all squares containing mine and thus he won . |
In above case used has clicked square containing mine and all mines exploded . Player has lost the game . |
So much so far. Now lets come to the coding part.
The applications main class is Main defined in file Main.java. Nothing special about this class except that it is application entry point(public static void main) , defines stage and scene for application and finally creates instance for class Grid wherein we have coded our game.
The applications main class is Main defined in file Main.java. Nothing special about this class except that it is application entry point(public static void main) , defines stage and scene for application and finally creates instance for class Grid wherein we have coded our game.
package minesweeper; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.paint.Color; import javafx.stage.Stage; public class Main extends Application { /** * @param args the command line arguments */ public static void main(String[] args) { Application.launch(Main.class, args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("Minesweeper v1.0"); primaryStage.setFullScreen(false); Group root = new Group(); Scene scene = new Scene(root,Color.BLACK); root.getChildren().add(new Grid(9,9)); primaryStage.setScene(scene); primaryStage.setVisible(true); } }In the whole project we have declared and used 4 classes. Main class we have just discussed above. Other 3 classes viz., Box ,Grid and Scoreboard are discussed below.
Box Class
Box class extends Parent class which is the base class for all nodes that have children in the scene graph. This class is used to draw a square in minesweeper.
Instance of Box Class |
- Uncovered Box : When user clicks a Box(square in minesweeper) the box gets uncovered. We are showing box is uncovered by changing color of box. Further there are two possibilities when a Box is clicked. 1) Clicked box don't have mines in adjacent 8 squares. In this case no count is shown. 2) Clicked box have mine(s) in adjacent 8 squares. In this case number of bombs in adjacent square is shown.
Uncovered Box with no bomb in adjacent squares. |
Uncovered Box with 2 bombs in adjacent squares. |
- Flagged Box: When user right clicks a box the Box gets flagged. We are flagging a box by showing flag image on it.
Flagged Box. |
- Exploded Box: When user clicks a Box having mine , the mine explodes. We are showing this by displaying image of explosion on Box.
Exploded Box. |
There are some methods declared that sets the state of Box. These are explained below.
- setBombBox() : This method is to add or remove bomb from Box. Attribute isBomb is set to true / false accordingly.
- showBombCount(): This method is to display number of mines in adjacent square. Attribute used is bomb_count.
- setCovered(): To uncover or cover a bomb.
- explodeBomb(): To show exploded Box if Box is having attribute isBomb = true.
- setFlagged(): Sets/Unsets the flag of the box. Attribute used is isFlagged.
- setBoxColor(): Sets color of the box.
- isBomb(),isCovered(),isFlagged() : As suggested in the method name itself it returns the boolean value of attribute.
- getBombCount: Returns number of bombs in adjacent squares of the box.
- resetBox(): This method resets all the attributes of Box and set the box to Covered state. This is used when to restart game.
- setBoxPosition() : Sets the value of attributes posRow and posCol using the parameters passed. This value is used to get Box position in the Grid.
- getBoxRow(),getBoxCol(): Returns posRow and posCol values respectively.
Thats all about Box class ! One thing should be remembered that Box class itself don't have game logic in it. It simply changes the state of the Box. It is the Grid class which dictates these changes and has game logic coded in it.
Grid Class
As the name suggests , Grid class is a Grid formed by Box objects. Like Box class, Grid class also extends Parent class.
Attributes of class are discussed in code snippet below. Please go through comments for the purpose of attributes.
Attributes of class are discussed in code snippet below. Please go through comments for the purpose of attributes.
int countColumn;//number of columns in the Grid. int countRow;//number of rows in the Grid. int countBomb;//number of Bombs(Mines) in the game. int countFlaggedBoxes=0;//number of boxes flagged by user. Box[][] boxGrid; //array to store objects of Box class. VBox vboxLayout; //layout to show children in vertical column ScoreBoard scoreBoard; //instance of inner class ScoreBoard. boolean isGameFinished = false; //whether game is finished
Next is the constructor of Grid class.
public Grid(int cols,int rows)
The Grid constructor has arguments number of columns and rows. Accordingly it initializes boxGrid array with specified number of objects.This is of course done within for loops. While doing this we are also setting position of Box object within Grid. Also we are adding mouse events setOnMouseClicked,setOnMouseEntered,setOnMouseExited for each Box object within this loop.
Box objects on the same row are added in HBox layout and this HBox is then added in vboxLayout in the end. Thus we have a Grid of Boxes. You can imagine this.
Finally , we call setGamePuzzle() method to set game puzzle.
Box objects on the same row are added in HBox layout and this HBox is then added in vboxLayout in the end. Thus we have a Grid of Boxes. You can imagine this.
Finally , we call setGamePuzzle() method to set game puzzle.
private void setGamePuzzle()
In this method we are first calculating total number of mines as 15% of total number of Boxes.
tempCountBomb = (int)((countColumn * countRow * 15.0)/100);
Then we place these many mines randomly in a Grid.
for (int i = 0; i < tempCountBomb; i++) { random_row=(int) (Math.random()*countRow); random_col=(int) (Math.random()*countColumn); boxGrid[random_row][random_col].setBombBox(true); }
There is a possibility that same pair of random row and column may generate twice and bomb will set twice for the same Box object. In such cases we are reducing count of bombs by 1.
After setting bombs for some Boxes we are initializing remaining Boxes which don't have bomb by number of bomb counts in the adjacent 8 squares. This is how game puzzle is set.
In the attributes list of Grid class you might have noticed ScoreBoard class. This is a inner class defined in class Grid. Purpose of scoreboard is to show total number of mines in the puzzle and guide user when he wins or losses games. It also have "RESTART GAME" button which resets the game.
Instance of ScoreBoard is created in the Grid constructor and added in vboxLayout.
At this point game is ready and presented to the player. Now players interaction with application starts.
After setting bombs for some Boxes we are initializing remaining Boxes which don't have bomb by number of bomb counts in the adjacent 8 squares. This is how game puzzle is set.
In the attributes list of Grid class you might have noticed ScoreBoard class. This is a inner class defined in class Grid. Purpose of scoreboard is to show total number of mines in the puzzle and guide user when he wins or losses games. It also have "RESTART GAME" button which resets the game.
ScoreBoard when game starts. |
ScoreBoard when player wins game. |
ScoreBoard when palyer losses game. |
At this point game is ready and presented to the player. Now players interaction with application starts.
- When user clicks a Box which happens to be a Bomb Box then he loses the game and other hidden bombs also explodes. We also update scoreboard with message "Game Over".
- When user clicks a Box which is not a Bomb Box then we have to uncover that box and show user number of bombs present in the adjacent squares. If the clicked box don't have any bomb in adjacent square then we have to uncover all 8 adjacent squares and show number of bombs in the adjacent square of these squares. The process is recursive. This is handled in method showBombCounts() which is recursive. To get idea of this refer the image below.
In above example player has clicked on a box which is marked in red color. |
- When player right clicks a box we have flag tha box. If box is already flagged then we have to remove that flag.
- When user just hovers over the Covered Box with mouse cursor, we are changing color of box when cursor is on the Box. As soon as cursor exits box we are showing earlier color.
Here ends the description of the coding part. Hope you like the post !
Your suggestions are most welcome.
If you want to download jar file of the game it can be downloaded here.
Javafx2.0 must be installed on your system to run this game. Get it from here.
it shows error @
ReplyDeletetxtMinesRemaining.setContent(Integer.toString(mine_remaining));
sweet
ReplyDeleteThanks !
Delete