Friday, June 29, 2012

Minesweeper Applet - Part 2

Introduction

This is part 2 of the series. It is recommended to read part 1 first. If you just want to play the game, you will need Mine.java in part 1 and MineApplet.java in part 2. Put both of them in the same folder and type :
javac *.java
java MineApplet
Part 1 can be found here:

Upload to web server

It is not necessary to have a web server in order to play this applet. Because it is written in such a way that a simple applet container is implemented in the code.

However, if you have a web server you may wish to upload the applet to share it. First you would need to create a jar file.

jar cvf mine.jar *.class
Then create an HTML file to hold the applet.

The user interface

It is almost identical to the Windows version of the MineSweeper. Left click to open a cell, right click to mark a mine, double click to auto-open safe neighbours.

All of the cells are implemented by JButton. I have extended the JButton class to MyButton for the following reasons:

  1. We can provide customize outlook of the button, for example, we may change the font color of the button according to the label. The standard MineSweeper game typically use red "1", green "2", red "3".
  2. We can draw an icon to the button. For example, the "new game" button at the top has a smiling face on it. See the paintComponent() method for details
  3. We can define mouse action listener for left click, right click and even double click. See the mouseClicked() method for details

Understanding the code

The logic of the game was implemented in Mine.java in part 1.
The GUI is implemented in MineApplet.java here.

Mine.java was explained in Part 1. I am not going to write detail explanation of MineApplet.java here. The best way to understand it is to play the game then view the code. It illustrate many useful techniques.

  1. It contains a simple applet container so that it can be run as an java application. If you are searching for "Applet to Application", you may find an example right here. See the main() method for details
  2. It contains JButton with customized look
  3. It contains JButton with customized control. It implements a JButton class with right click and double click support.
  4. It uses the technique of embedding image into source code so that no separated image files are needed. See buildSmileImage() for details.
  5. It implements a timer thread to display the timer. The timer thread conform to the standard of the applet life cycle. See the start(), run() and stop() method.

Full source listing

Minesweeper Applet - Part 1

Introduction

We are going to implement a mine sweeper game in Java. The game can be executed as an applet and as an application.

Text Mode

It is simpler to implement the game in text mode. Not only the code is simpler but also it is much easier to debug. We will implement the game in text mode first, then add a GUI after the game is working.

Data Structure

We will use a simple single dimensional array to represent the mine field. We will use the number 64 to represent a mine. We will hard code the mine field at the moment. Later we will add code to generate a random mine field.

Counting the neighboring mines

What we want :

  0  1  1  1  0  1 64  1  0
  0  1 64  1  0  2  2  2  0
  0  1  1  1  0  2 64  2  0
  0  0  0  0  0  2 64  3  1
  0  0  0  0  0  1  2  3 64
  0  1  1  1  0  0  2 64  3
  0  1 64  1  0  0  2 64  2
  1  2  1  1  0  0  1  2  2
 64  1  0  0  0  0  0  1 64
What we do : Debugging

As previously said, it is easier to debug a text mode program, we will write a simple method to display the mine field. M1.java

This is the first version of our mine sweeper, it just print out a hard code mine field, with the correct neighboring counts. Sample run :

 
javac *.java

java M1
  0  1  1  1  0  1 64  1  0
  0  1 64  1  0  2  2  2  0
  0  1  1  1  0  2 64  2  0
  0  0  0  0  0  2 64  3  1
  0  0  0  0  0  1  2  3 64
  0  1  1  1  0  0  2 64  3
  0  1 64  1  0  0  2 64  2
  1  2  1  1  0  0  1  2  2
 64  1  0  0  0  0  0  1 64
Hiding all the cells

We will hide the mine field by setting bit 7 of all cells to one. We would need to modify printField() as well. Now we have the second version of MineSweeper Sample Run:

 

javac M2.java

java M2

  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
Opening a Cell

For example, to open cell number 2 in the field, add the following in main() Test run:

 

  .  .  1  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
This is a "1". That means one of the neighbouring cell is a mine.

To open cell number 0, use the following Test run:

 


  0  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .
  .  .  .  .  .  .  .  .  .

Since this is zero, we can be sure the three neighbouring cells are safe to open. So we open them automatically. Test run:
 

  0  1  .  1  0  1  .  .  .
  0  1  .  1  0  2  .  .  .
  0  1  1  1  0  2  .  .  .
  0  0  0  0  0  2  .  .  .
  0  0  0  0  0  1  2  .  .
  0  1  1  1  0  0  2  .  .
  0  1  .  1  0  0  2  .  .
  1  2  1  1  0  0  1  2  .
  .  1  0  0  0  0  0  1  .

We are so lucky that most of the cell are automatically opened.

Next we complete the text mode minesweeper. The user can enter any number between 0 to 63 to open a cell. Coming next

Though we have a working mine sweeper, it is quite difficult to play in text mode. We will make an applet version of the game. We won't reinvent the wheel and Mine.java would be completely reused without modification. We will just add a GUI wrapper.

Continue with part 2 here ...