Lab 8: Mine Camp, Part I

Objectives

In this lab, you'll write a puzzle program based on Minesweeper, using Java's built-in Swing libraries. You can access a version under the Games submenu of the K-menu. Our version will be considerably simpler; Figure 8.1 contains a screen shot.


Figure 8.1: A screen shot of Mine Camp.

This program has a 10x10 grid of buttons, hiding 20 randomly placed mines. Initially all are light gray, containing the label ``??''. If you click on a button hiding a mine, the button turns red and displays the new label ``B''. If you click on a button that has no mine beneath it, then the button turns green and displays the number of adjacent buttons that hide mines. (Adjacent buttons include buttons that share only a corner.)

The goal is to click on all the button that hide mines, without clicking on any that hide mines. Figure 8.1 illustrates a game where the user has won. The assigned program does not detect whether the game has been won or lost.

The File menu of the program contains a New option for resetting the board, and a Quit option for closing the program. Closing the window closes the program also.

Part A. The MineButton class

MineButton, a subclass of JButton, represents a single button in the grid.

MineButton(MineCamp board, int col, int row)
Creates a button located in column col and row row of board. (Actually, you won't need this information for any MineButton methods in this lab. They are for the sequel.)

The class supports the following instance methods.

void reset()
Resets the button so that it is no longer hiding any mines. It sets the button background to be light gray, and the label to be ``??''. (JButton's instance methods setBackground() and setText() are useful for accomplishing these feats.)

void setMined()
Tells the button that it is hiding a mine.

boolean isMined()
Returns true if the button is hiding a mine.

void setCount(int value)
Tells the button that it has value neighbors that are hiding mines.

int getCount()
Returns the number of neighbors that hide mines.

void reveal()
Reveals whether the button hides a mine. If the button hides a mine, its background color should change to red and its label should change to ``B''. If the button does not hide a mine, its background color should change to green and its label should change to a count of how many neighbors are mined.

boolean isRevealed()
Returns true if the button has been revealed since it was last reset. (This method exists for the sequel.)

The button should be configured so that clicking on it calls its reveal() method.

Part B. The MineCamp class

MineCamp, which extends JFrame, represents the application window. It primary job is to hold and initialize the 100 MineButtons, although it also must handle closing the program when requested and recompute the mines when appropriate.

The class should define the constants WIDTH, HEIGHT, and NUM_MINES to represent the width of the grid, the height of the grid, and the number of buttons hiding mines.

To hold the MineButtons, the constructor should use an instance variable that holds a two-dimensional array of MineButtons. I named this instance variable mines.

The constructor should fill this array with buttons, and then it should call a method reset() to initialize the buttons to a new board. (You want to define a separate method for this, so that you can use the same code when the user selects New from the File menu also.) The constructor should also place the buttons into the window, as well as set up the menu.

The following code is useful in the reset() method for initializing the MineButtons so that exactly NUM_MINES buttons hide mines.

for(int i = 0; i < WIDTH; i++) {
    for(int j = 0; j < HEIGHT; j++) {
        mines[i][j].reset();
    }
}
for(int k = 0; k < NUM_MINES; k++) {
    int i, j;
    do {
        i = (int) (WIDTH * Math.random());
        j = (int) (HEIGHT * Math.random());
    } while(mines[i][j].isMined());
    mines[i][j].setMined();
}
After the above, reset() also needs to compute the counts for each MineButton.

The MineCamp class will define the main() method, which should simply create a new MineCamp object.