CS 124, Fall 2009
Lab 9: Dice (Writing a Class and Using Arrays)

This week's lab consists of one fairly short exercise in which you will write a class from scratch. That class will be similar to the PairOfDice examples in the textbook, but it will use an array to represent the numbers showing on a list of any given number of dice. In addition to this exercise, there is a new longer-term project in which you will work on a basic "MineSweeper" game. Programming this game will require you to work with two-dimensional arrays.

To begin the lab, you should create a directory or Eclipse project named lab9 and copy the file named DiceStats.java from /classes/f09/cs124 into your lab9 folder. Note that this file will have compilation errors, since it requires another class, ListOfDice. You will write that class.

The single exercise of lab is due next Thursday, November 5, as usual. The MineSweeper project will be due in a couple weeks.

Exercise: Writing a "ListOfDice" Class

The DiceStats program performs a probability experiment. It rolls a set of dice over and over, and it keeps track of how many times each possible roll comes up. It then prints out information about the data it has collected, to give you an idea of the probability that each possible total will occur. You can find a sample output from the program at the end of the file.

Although we will discuss this program in class, you don't really need to understand it completely. The point is that the program used a class named ListOfDice to represent the dice that it rolls. You need to write a ListOfDice class that will meet the requirements of the DiceStats program (without changing DiceStats at all). So, start writing the ListOfDice class. Remember that this is a class for making objects, so nothing in the class will be static. The class must contain:

Once you have completed ListOfDice, you should be able to run DiceStats and see that it works correctly.

Don't forget to add JavaDoc-style comments to the code that you write, and to follow all the other rules of good programming style!


Longer Project 3: MineSweeper (with 2D Arrays)

For the third longer-term project, you will work on a MineSweeper game. If you are not already familiar with this common game, you try it in the applets given below. The game has a 10-by-10 grid of squares. Each square might or might not contain a mine. The point of the game is to try to mark each square as mined or safe (that is has no mine). There are exactly 10 mines scattered around the grid. A square can only contain one mine, so there are 10 squares that contain mines.Click on a square that you think (or hope) is safe. If it actually contains a mine, you will be blown up, and you lose the game. If the square does not contain a mine, it will turn light green. Furthermore, if there are any mines in neighboring squares, then the number of mines in the neighboring squares will be displayed in the square. For example, if a 2 appears in the square, that means that two of the neighboring squares are mined. (Neighbors are squares that are next to the given square, horizontally, vertically, or diagonally. A square in the middle of the board has 8 neighbors. Square on the edges have fewer than 8 neighbors.) Note that if a square turns light green with no number displayed, it means that none of the neighboring squares contain mines. In that case, you can click on all the neighbors, since you know that they are safe.

If you believe that a square contains a mine, you should right-click that square (or shift-click). The square will turn a light red color to remind you that you believe it to contain a mine. We say that the square is "flagged" as being unsafe. Clicking a red square will have no effect. (You are protected from accidently blowing yourself up by clicking on it.) But if you right-click (or shift-click) a red square, it changes back to dark green, so if you change your mind that the square contains a bomb, just right-click it again.

To win the game, you must mark every square as being safe or as being mined. That is, you must get rid of all the dark green squares. When the game ends, whether you win or lose, the positions of all the mines are revealed. If you want to play another game, click the "New Game" button.

Here are two versions of the game. They are identical except for one thing: In the version on the right, when you click on a safe square and there are no mines in its neighbors, then all the neighbors are automatically clicked for you. In the version on the left, you have to click on them all yourself, which makes the play more tedious.

          

To begin work on this project, copy the files MineSweeper.java and MineSweeperBoard.java into a folder in your account. You can find these files in /classes/f09/cs124. (You can create a new project or folder for this, or put it in your lab9 if you prefer.)

You will be working in the file MineSweeperBoard.java, which defines the game board and the logic of the game. You should read through this file and try to understand it. The main program for the application is MineSweeper.java, but you will not have to modify it. When you run MineSweeper, you'll see that some of the work on the game has been done. The board shows a grid of dark green squares, with an "X" drawn in each square. Clicking on a square changes that square to light green. Right-clicking or shift-clicking changes a square to light red.

The information about the color or "state" of all the squares is stored in an instance named state, which is a two dimensional array of type int[][]. The possible values in this array are given by some constants: HIDDEN, REVEALED, and FLAGGED_AS_MINED. When the array is created in the newGame method, all the values in the array are HIDDEN. The value of state[row][col] changes when the user clicks the square in row row, column col. The paintComponentmethod uses the value of state[row][col] to decide what color to use to fill the square.

Your job is to complete the game. Right now, there is nothing in the game about mines. You will have to add that, along with most of the game logic. Here are some things that you need to do...

  1. Add an array to keep track of where the mines are. This can be an instance variable of type boolean[][].
  2. Add code to the newGame method to create the array and place ten mines in random locations. That is, you have to set ten randomly selected values in the array to true. To test this, you might modify paintComponent so that it only puts an "X" in a square if there is a mine in that square.
  3. Write a method to count the number of mines in the neighbors of a given square. You will need this method so that you can display the information to the user. You might test this method by modifying the paintComponent method so that it displays the count in each square (that does not contain a mine). Note: To draw a numerical value in paintComponent, you need to convert the number to a String to use in the drawString method. If n is a number, you can compute the corresponding string as ""+n.
  4. Implement the basic game logic in the mousePressed method. For example, if the user clicks a HIDDEN square that contains a mine, then the game ends. You will also need to modify the paintComponent method so that the number of mined neighbors is only displayed in REVEALED squares. This is not a complete description of what you need to do! You will need to think about all the cases that need to be handled.
  5. Add code to mousePressed to test whether the user has won the game. The user wins when there are no more HIDDEN squares on the board. Note that when the game ends for any reason, you should set the variable gameInProgress to false. Note that paintComponent should show the locations of the mines only when If gameInProgress is false.