Hour 21

Playing Games with Java

At this point, you have more than enough Java programming skills to be a danger to yourself and others. You can write programs for the World Wide Web and programs to run locally on your computer. The next several hours will test your skills as you apply them to some practical examples of programming.

The program you'll be writing during this hour and the next hour will serve two purposes. First, it will give you a chance to create an object and use it in another program. Second, you'll be building gambling skills that will hold you in good stead at the next illicit gambling den you visit. During this hour, you'll create a Die object and test it out with a simple Java program. Once it works, you'll be using the Die object in a Craps applet during Hour 22, "Writing a Game for the Web."

The following topics will be covered during this hour:

Craps

Everyone has different recollections of childhood, but who doesn't have memories of skipping school, staying out all night, and blowing all your lunch money at the craps table with some of the neighborhood drug dealers? Most of us don't have these memories, unfortunately, because of restrictive parents and their crazy notion that a good education and sleep were important for their kids.

Luckily, you can simulate a little of that gambling den experience by playing a craps game on your computer. Craps, in case you're particularly sheltered, is a game involving two six-sided dice. The goal is to roll a winning number with the dice before you roll a losing number. Craps has some complicated rules for gambling, but the program you'll write during this hour will focus on dice rolling, winning numbers, and losing numbers. The number of winning rolls and losing rolls will be totaled up as you play, giving you an idea of how often a craps player rolls a winning pair of dice.

When a player rolls the dice for the first time, any combination of the two dice that adds up to 7 or 11 is a winner. Any dice total that equals 2, 3, or 12 is an immediate loser and is called craps, as in "Oh, crap, I just lost the money I needed for liposuction surgery!" If the first roll is not an immediate winner or a loser, the total of the dice becomes known as the point. For all successive rolls, the player will win a game if the point is rolled again. However, if a 7 is rolled before the point is rolled, the player craps out.

The following is a sample game rolled by motion picture star Pia Zadora:

1. Pia rolls a 5 and a 6, adding up to 11. She wins the game instantly.

That example wasn't long enough for illustrative purposes, so here's another game from Ms. Zadora:

1. Pia rolls a 6 and a 2. This roll makes 8 the point. On all successive rolls, an 8 will win, and a 7 will lose.

2.
Pia rolls a 4 and a 2, adding up to 6. She must roll again.

3.
Pia rolls snake eyes--2. She didn't roll the point (8), so she has to roll again.

4.
Pia rolls a 3 and 4 (for a total of 7), crapping out.

Now that you know how craps works, it's time to teach the game to your computer. When you're done, you'll be writing a Craps applet that you can put on a World Wide Web page.

Organizing the Program

Before you tackle any programming project, spend some time thinking about how it should be implemented. Planning ahead can prevent you from doing work in the program that has to be redone later because it wasn't done correctly. It also can make the finished program easier to understand and easier to maintain later on.

If you're particularly organized, you might want to create a flowchart that illustrates the way the program will function. Flowcharts are an effective way to demonstrate the logic a computer should follow as it handles a program. Even if you don't create flowcharts, you should make a list of the things your program must do. Think about each task that must be handled for the program to work, and don't worry about putting them in any order.

For example, the Craps applet includes the following list of tasks:

As you can see, almost all aspects of the Craps applet will involve the dice. During Hour 10, "Creating Your First Object," you saw how a computer program can be thought of as a group of objects that work together to accomplish a task. One way to conceptualize the Craps program is to create an object that represents a six-sided die. If you can create a Die class that can roll itself, draw itself, and keep track of its own value, most of the work of a Craps applet will be done. An advantage to creating a separate Die class of objects is that you can use this class in any program you write that involves dice. The only things left for the applet to do are to create two Die objects, ask them to roll themselves, take user input, and keep score.

Creating a Die Class

The Die class of objects that you will create must handle the following tasks:

Using your word processor, create a new file named Die.java. Each section of the Die class will be described as you enter the text. Begin with the following line:

import java.awt.*;

This line makes Java's Abstract Windowing Toolkit classes available for use in the Die class.

Throughout this section, Die is described as a class of objects rather than as a program. Class, object, and program are largely synonymous in Java, but it's helpful to think of them in the following way: A program is a set of computer instructions that handle a task. Objects are used by a program to accomplish its work. A class is the template that determines how an object is created and what it can do.

After adding a blank line, enter the following statements:

public class Die {
    public int value;

The first line begins the Die class and indicates that the name of the source file should be Die.java. Die does not use the extends statement along with public class, so it does not inherit any capabilities from other objects. It's a unique class of objects.

The second line creates an integer variable called value. This variable will be used to store the value of the die after it is rolled. Because the object is a six-sided die, the variable will store a value ranging from 1 to 6.

Setting Up Initial Values

The first task that the Die object must handle is to set up any variables that are needed when the object is created. Insert a blank line after public int value; and then enter the following:

public Die() {
    value = 0;
}

This method is called a constructor because it is called automatically whenever another program creates a Die object. The method does only one thing: It sets the value variable equal to 0.

Rolling the Die

The next step is to write a method that handles the rolling of the die. Insert a blank line at the bottom of your file and then enter the following:

public void rollValue(int maxValue) {
    double tempValue = Math.random() * maxValue;
    value = (int) Math.floor(tempValue) + 1; 
}

This method takes one argument, an integer called maxValue. This value will be used to indicate the number of sides on the die. The program you're writing, a Craps applet, always uses six-sided dice. However, by using an argument to enable other types of dice to be used, you make the Die class of objects more useful with other projects you might undertake.

Two methods of the Math class are used in the rollValue() method: Math.floor() and Math.random(). The Math class is one of the standard class libraries that are part of the Java language, and it has several functions to handle mathematic operations. Math.random() generates a random number ranging from 0.0 to 1.0. These numbers are long floating-point numbers such as the following:

0.7359693177023363
0.5431408045289557
0.03239819056314541

When you multiply Math.random() by a value, you create a random number ranging from 0 to within .001 of that value. For instance, multiplying Math.random() by 6 generates a number ranging from 0.0 to almost 6.0. Adding 1 to this, as the rollValue() method does, generates a random number from 1.0 to almost 7.0.

But just try rolling a six-sided die until you come up with 2.71570402264! To create a dice-like effect, the number must be rounded down to an integer. The Math.floor() method does exactly this. By using both floor() and random(), the rollValue() method generates a random number from 1 to maxValue and stores the number in the value variable.

Drawing the Die

The last thing the Die class of objects needs to do is draw the die. Instead of displaying the value of the die as text, you can make your program more appealing by showing the die on-screen. Java has several different polygon-drawing methods that you can use to depict a die. The final look of a die depends on its value. Figure 21.1 shows six dice with values that range from 1 to 6.

Figure 21.1. The possible values on a six-sided die.

You can show dice in a computer program by drawing a rectangle with rounded corners and circles for each number on a side. One way to handle this procedure in a Java program would be to use a switch-case block with six different sets of drawing statements. One dot could be drawn for a 1, two dots could depict a 2, and so on. However, this solution involves a lot of redundant statements because many of the faces on a six-sided die contain the same dots. As you can see in Figure 21.1, values 2 through 6 all have dots in the upper-left corner and lower-right corner. Using switch and case would require the same statements to be repeated five times for these dots.

Instead of repeating the same statements in several places, you can take a different approach. Figure 21.2 shows each dot that might be seen on a die and the values that are associated with the dot. You can use this information to draw a die more simply.

Listing 21.1 shows the full source code of the file Die.java. All of the statements you have entered up to this point should look like Lines 1-13. Go to the bottom of your file and insert Lines 14-37 of Listing 21.1. Save the file when you're done.

Figure 21.2. Matching the dots to the values associated with them.

Listing 21.1. The source code of Die.java.


 1: import java.awt.*;
 2:
 3: public class Die {
 4:     public int value;
 5:
 6:     public Die() {
 7:         value = 0;
 8:     }
 9:
10:     public void rollValue(int maxValue) {
11:         double tempValue = Math.random() * maxValue;
12:         value = (int) Math.floor( tempValue ) + 1;
13:     }
14:
15:     public void drawDie(Graphics screen, int x, int y) {
16:         screen.setColor(Color.red);
17:         screen.fillRoundRect(x, y, 100, 100, 20, 20);
18:         screen.setColor(Color.black);
19:         screen.drawRoundRect(x, y, 100, 100, 20, 20);
20:         screen.setColor(Color.white);
21:         if (value > 1) {
22:             screen.fillOval(x+5, y+5, 20, 20);
23:             screen.fillOval(x+75, y+75, 20, 20);
24:         }
25:         if (value > 3) {
26:             screen.fillOval(x+75, y+5, 20, 20);
27:             screen.fillOval(x+5, y+75, 20, 20);
28:         }
29:         if (value == 6) {
30:             screen.fillOval(x+5, y+40, 20, 20);
31:             screen.fillOval(x+75, y+40, 20, 20);
32:         }
33:         if (value % 2 == 1) {
34:             screen.fillOval(x+40, y+40, 20, 20);
35:         }
36:     }
37: } The drawDie() method takes three arguments:

The following things are taking place in the drawDie() method:

Save the file, using the name Die.java, and compile it. Once it compiles successfully, you will have a Die class of objects that can be used in any program where you want to use six-sided dice.

Testing the Die Class

The Die class of objects that you have created isn't intended to function as a stand-alone program. If you tried to run it with the java tool, it would result in an error because there is no main() statement in the Die class. To try out your new class, you need to use it inside another Java program. You can do this in the same way you used classes such as Math, Graphics, and Color in your Die class. Create a new file with your word processor and call it TestDie.java. Enter the text of Listing 21.2 and save the file.

Listing 21.2. The full source code of TestDie.java.


 1: class TestDie {
 2:     public static void main(String[] arguments) {
 3:         Die firstDie = new Die();
 4:         Die secondDie = new Die();
 5:         firstDie.rollValue(6);
 6:         secondDie.rollValue(6);
 7:         System.out.println("The first die rolled a " + firstDie.value);
 8:         System.out.println("The second die rolled a " + secondDie.value);
 9:     }
10: } 


This program creates two dice called firstDie and secondDie, rolls each of them using the rollValue() method, and displays the value stored in the value variable of each Die object. The argument of 6 is used with the rollValue() method in Lines 5 and 6. This argument causes a dice roll ranging from 1 to 6 to occur, and the result is stored in value.

Compile TestDie.java and run it from the command line with the java tool. The output should resemble the following:

The first die rolled a 2
The second die rolled a 5

Run it several times to see that the rolls of the dice are random.

As with most programming languages, Java does not generate completely random numbers. However, the results are random enough for most uses. One use that the Random class would not be sufficient for is encryption. Java 1.1 introduces a new subclass of Random called SecureRandom. This class can be used in Java programs that encrypt information so that it cannot be viewed without being decrypted first.

Summary

This hour provided some practical experience with the object-oriented approach of the Java language. The Die class of objects that you created simulates the behavior of a type of real-world object: a six-sided die. Object-oriented programming requires more initial effort than some other approaches, but it has several advantages:

You now have the Die class of objects to use whenever a die needs to be used in a program. You'll be using it in a Craps applet in the coming hour.

Q&A

Q Does the Craps applet require the use of a class of objects to represent the dice?

A
It's not a requirement--you could combine all the dice-related tasks and the scorekeeping tasks into the same Java program. If you look at the source code of applets that are available on the World Wide Web, you'll see many that handle all of their functionality within a single program. However, this type of structure doesn't take advantage of the benefits of object-oriented programming, and the program is harder to understand, harder to reuse elsewhere, and more prone to bugs.

Q Does the public statement in front of a variable declaration mean that the variable can be modified from other Java programs?

A
Yes. As you'll see in the Craps applet in the next hour, you can change the value of public variables in other objects. If you create a Die object with the name firstDie, you can set its value variable with a statement such as the following:
firstDie.value = 0;
Q Can you have more than one constructor method in a class of objects?

A
You can have more than one constructor method if they have different argument lists within their parentheses. One constructor could have no arguments, as in public Die(), and another permitted constructor could be public Die(int maxValue). One would be used when Die() is used in a program without any arguments, and the other would be used when Die() is used with a single integer as an argument.

Q Where can I find out the full list of classes that I can use in my Java programs and the public methods that can be used with these classes?

A
The Java Developer's Kit includes a large number of Web pages that document all classes that are standard parts of the Java programming language. You also can view these pages at the JavaSoft Web site with any Web browser. Visit the following page:
http://www.javasoft.com/products/JDK/1.1/docs/
Q What colors can be used in conjunction with the setColor() method?

A
In addition to red, black, and white, you can use the following variables as an argument to setColor(): blue, cyan, darkGray, gray, green, lightGray, magenta, orange, pink, and yellow. There also are methods of the Color class that can be used to create a color based on RGB values, a popular system for specifying a wide range of possible colors. RGB values are used on Web pages with the BGCOLOR attribute of the <BODY> tag.

Quiz

Roll the dice and put your knowledge of object creation on the line by answering the following questions.

Questions

1. What's the name for a method that is automatically called when an object is created?

(a) an automat
(b) a constructor
(c) an init() method

2.
In Java, which of the following isn't a synonym for program?

(a) a class
(b) a method
(c) an object

3.
What's the name of the method in the Math class that rounds a number down to the next lowest integer?

(a) floor()
(b) round()
(c) below()

Answers

1. b. An object's constructor method is called when it is created. The init() method might sound familiar because it's handled automatically when an applet is first loaded.

2.
b. A program also can be considered as a class of objects or an object itself.

3.
a. The round() method adds 0.5 to a number before finding the next lowest integer, rounding it off to the closest integer.

Activities

Before you continue to the Craps applet, you can expand your knowledge of this hour's topics with the following activities: