With the Die class you created during the last hour, you can add dice to any of your Java programs. The Craps program that you will be writing during this hour uses two dice. Most of the tasks you have to handle in your game are taken care of by the Die class. What's left for your Craps applet is to display information to users, take input from users, and keep score.
The following topics will be covered during this hour:
All applets that you create will have some methods in common. The init() method is called when an applet loads on a page for the first time; you can use this method to set up variables and handle other startup tasks. The paint() method is called whenever something should be updated on the display. It also can be called within a program with the repaint(); statement. The init() and paint() methods will be used in your Craps applet. You also will use the actionPerformed() method, which is called whenever a user does something to a graphical item such as clicking on a button or hitting Enter in a text field.
Create a skeletal version of Craps that can be filled in during the hour as each section of the program is discussed. Create a new file in your word processor and enter Listing 22.1. Save it under the name Craps.java, making sure that it is saved in the same directory as Die.java and Die.class.
1: import java.awt.*; 2: import java.awt.event.*; 3: 4: public class Craps extends java.applet.Applet implements ActionListener { 5: // create variables here 6: 7: public void init() { 8: // initialize program 9: } 10: 11: public void paint(Graphics screen) { 12: // display stuff 13: } 14: 15: public void actionPerformed(ActionEvent event) { 16: // receive user input 17: } 18: 19: public void checkResult(Die d1, Die d2) { 20: // check roll and keep score 21: } 22: }
In addition to the init(), paint(), and actionPerformed()
methods, this skeletal version of the Craps applet includes a checkResult()
method with two Die objects as parameters. As you will see, this method
is used to check the results of a dice roll and keep score.
The first task in the Craps applet is to set up all variables that are going to be used in the program. In your word processor, delete the comment line // create variables here and enter Listing 22.2 in its place.
1: Die die1 = new Die(); 2: Die die2 = new Die(); 3: int wins = 0; 4: int losses = 0; 5: int point = 0; 6: final String WINNER = "WINNER"; 7: final String LOSER = "CRAPS!"; 8: String resultText = ""; 9: Button rollButton = new Button("Roll Dice");
Lines 1 and 2 create new Die variables called die1 and die2.
These variables are set up in the same way other variables such as strings are created
by using the class name, variable name, and the new statement. When this
statement is handled in your program, a constructor method of the Die class
is called. Because there's nothing in between the parentheses in new Die(),
the matching constructor with no arguments is called in the Die class.
In Lines 3 and 4, two integer variables are used to keep track of a user's win/loss record: wins and losses. The point integer variable in Line 5 stores the point, which is the dice total that must be rolled to win in a craps game after the first roll.
Lines 6 and 7 create strings named WINNER and LOSER. The final statement is used to declare that these variables are constants. A constant is a variable that will never change in value as a program runs. To provide another hint that the variables are constants, the names WINNER and LOSER are capitalized.
Because constants never change in value, you might wonder why one should ever be used. You could just use the value of the constant throughout the program. The advantage of using constants is that they can make a program easier to understand. For example, the variables Font.BOLD and Font.ITALIC are constants that hold integer values representing the style of the current font. The statement Font("Helvetica", Font.BOLD, 12) provides more information than Font("Helvetica", 1, 12) does, and both statements make 12-point Helvetica Bold the current font for text display.
Line 8 sets up a string called resultText and sets it up with an initial value of ""--an empty string. The last line, 9, creates a Button object called rollButton. As this object is created, the string "Roll Dice" is sent to the constructor method of the object. Button is a class of objects that handle the display and function of clickable user buttons. The rollButton object is given the label Roll Dice. This button is shown in the applet window, and it gives the user a chance to request a dice roll.
A few things need to be done when the Craps applet first runs on a Web page. You need to choose a background color for the window and add the Button object rollButton to the window. To do these things, replace the comment line // initialize program with Listing 22.3.
1: setBackground(Color.green); 2: rollButton.addActionListener(this); 3: add(rollButton);
In Line 1 of Listing 22.3, the constant Color.green is used with the setBackground()
method to choose green as the background color of the applet window. When the paint()
method is called automatically to display the applet on-screen, it uses the color
defined in setBackground(). If there is no setBackground() statement
in a Java program, the default is gray.
Line 2 makes it possible for the rollButton object to generate action events when it is clicked. This is done by using the addActionListener() method, which is part of the ActionListener interface. Line 3 adds the rollButton object to the applet window.
The paint() method is called any time the text and graphics on-screen should be updated. This situation occurs when the program is run to draw something onto a blank window. The paint() method also can be called any time one of the following takes place:
In your growing Craps.java file, delete the comment line // display stuff inside the paint() method. Replace it with Listing 22.4.
1: die1.drawDie(screen, 5, 50); 2: die2.drawDie(screen, 175, 50); 3: screen.setColor(Color.black); 4: Font f = new Font("Helvetica", Font.BOLD, 15); 5: screen.setFont(f); 6: if (point != 0) 7: screen.drawString(point + " wins and 7 craps out.", 5, 200); 8: else 9: screen.drawString("7 or 11 win; 2, 3, or 12 crap out.", 5, 200); 10: screen.drawString("Number of wins: " + wins, 5, 220); 11: screen.drawString("Number of losses: " + losses, 5, 240); 12: if (resultText != "") { 13: f = new Font("Helvetica", Font.BOLD, 30); 14: screen.setFont(f); 15: screen.drawString(resultText, 85, 110); 16: resultText = ""; 17: } The following things are taking place in this method:
The text that is displayed in the paint() method depends on several things that are going on in other parts of the program. Because the rolls needed to win or lose change at different points in a game, paint() uses the value of point to determine what should be displayed. The variable point equals 0 at the beginning of a new game of craps because there is no point until the first roll is over. The resultText variable is displayed only when a game is over. It is set initially in another part of the program, the checkResult() method.
Go to the spot in your Craps program with the comment line // receive user input and replace it with Listing 22.5.
1: die1.rollValue(6); 2: die2.rollValue(6); 3: checkResult(die1, die2); 4: repaint();
As you learned during Chapter 20, "Responding to User Events," the actionPerformed()
method is called whenever an action event occurs on a component that can send out
those events. The Craps applet has only one user interface component, a
Button object called rollButton, which has been set up with an
ActionListener object so it can generate action events.
The rollButton object in this program is labeled with the text Roll Dice. When the button is clicked, Lines 1 and 2 call the rollValue() method of each Die object. The argument, 6, indicates that a number from 1 to 6 should be rolled on each die. When a Die is rolled, the value variable is updated with the die's new value.
After the dice roll, you should see whether the new total of the dice is a winner or loser. You do this by calling the checkResult() method of the applet with two arguments: die1 and die2, the two Die objects. The checkResult() method is detailed in the next section.
Line 4 calls the repaint() method to force the screen to be updated. This method is needed because the dice and other information change with each roll, and those changes should be reflected on-screen.
The last thing to handle in the Craps applet is scorekeeping. The checkResult() method of your program takes two Die objects as arguments. Delete the comment line // check roll and keep score and replace it with Listing 22.6.
1: if (point == 0) { 2: point = d1.value + d2.value; 3: if ( (point == 7) | (point == 11) ) 4: resultText = WINNER; 5: if ( (point < 4) | (point == 12) ) 6: resultText = LOSER; 7: } else { 8: if (d1.value + d2.value == point) 9: resultText = WINNER; 10: if (d1.value + d2.value == 7) 11: resultText = LOSER; 12: } 13: if (resultText == WINNER) { 14: wins++; 15: point = 0; 16: } 17: if (resultText == LOSER) { 18: losses++; 19: point = 0; 20: }
Lines 2 -6 of this method are handled only if the point variable is equal
to 0. The point variable is used throughout this program as an
indicator of the current stage of the craps game. When point equals 0,
it shows that the current craps game has just finished its first roll, because the
point has not been established yet. If point does not equal 0,
the current game must be in its second or successive rolls. When point equals
0, Line 2 sets point to the sum of the value variables
of both Die objects. The value variable keeps track of each die's
current value in the game.
Lines 3-6 determine whether a winning roll or a losing roll has happened in the first roll of a craps game. The dice totals of 7 and 11 are winners, and the totals of 2, 3, or 12 are losers. The OR operator | is used in Lines 3 and 5, so if either one equality test or the other is true, the following statement is handled. If point is equal to 7 or point is equal to 11, the resultText variable is set to the value of the WINNER variable, which is the text WINNER. If point is less than 4 or point is equal to 12, resultText is set to the value of the LOSER variable, which is CRAPS!.
Lines 8-11 of this method are handled only if point did not equal 0 in Line 1. Line 8 tests whether the current total of the dice is equal to point. If it is, the resultText variable is set to the value of the WINNER variable, which is WINNER. Line 10 tests whether the current dice total equals 7. If it does, resultText is set to equal the LOSER variable, which is CRAPS!
Lines 13-16 are handled if resultText is equal to the WINNER variable, which indicates that the current dice roll was a winner. The wins variable is increased by 1 in Line 14 by the increment operator ++. Also, the point variable is set to 0 in Line 15 so that a new game can begin.
Lines 17-20 are handled if resultText is equal to the LOSER variable. These lines cause the losses variable to increase by 1 and point to be set to 0 in Line 19.
When you're done adding these statements inside the checkResult() method, your program should resemble Listing 22.7. The only differences should be if you indented the program differently, but all statements should be identical. Save your Craps.java file.
1: import java.awt.*; 2: import java.awt.event.*; 3: 4: public class Craps extends java.applet.Applet implements ActionListener { 5: Die die1 = new Die(); 6: Die die2 = new Die(); 7: int wins = 0; 8: int losses = 0; 9: int point = 0; 10: final String WINNER = "WINNER"; 11: final String LOSER = "CRAPS!"; 12: String resultText = ""; 13: Button rollButton = new Button("Roll Dice"); 14: 15: public void init() { 16: setBackground(Color.green); 17: rollButton.addActionListener(this); 18: add(rollButton); 19: } 20: 21: public void paint(Graphics screen) { 22: die1.drawDie(screen, 5, 50); 23: die2.drawDie(screen, 175, 50); 24: screen.setColor(Color.black); 25: Font f = new Font("Helvetica", Font.BOLD, 15); 26: screen.setFont(f); 27: if (point != 0) 28: screen.drawString(point + " wins and 7 craps out.", 5, 200); 29: else 30: screen.drawString("7 or 11 win; 2, 3, or 12 crap out.", 5, 200); 31: screen.drawString("Number of wins: " + wins, 5, 220); 32: screen.drawString("Number of losses: " + losses, 5, 240); 33: if (resultText != "") { 34: f = new Font("Helvetica", Font.BOLD, 30); 35: screen.setFont(f); 36: screen.drawString(resultText, 85, 110); 37: resultText = ""; 38: } 39: } 40: 41: public void actionPerformed(ActionEvent event) { 42: die1.rollValue(6); 43: die2.rollValue(6); 44: checkResult(die1, die2); 45: repaint(); 46: } 47: 48: public void checkResult(Die d1, Die d2) { 49: if (point == 0) { 50: point = d1.value + d2.value; 51: if ( (point == 7) | (point == 11) ) 52: resultText = WINNER; 53: if ( (point < 4) | (point == 12) ) 54: resultText = LOSER; 55: } else { 56: if (d1.value + d2.value == point) 57: resultText = WINNER; 58: if (d1.value + d2.value == 7) 59: resultText = LOSER; 60: } 61: if (resultText == WINNER) { 62: wins++; 63: point = 0; 64: } 65: if (resultText == LOSER) { 66: losses++; 67: point = 0; 68: } 69: } 70: } Compile the Craps.java file using the following command: javac Craps.java
After fixing any errors that are caused by typos, you're almost ready to test the program.
Because the Craps program is an applet, it was designed to run only as part of a World Wide Web page. To place the applet on a Web page, create a new file called Craps.asp. Enter Listing 22.8 and save the file in the same directory as Craps.java and Craps.class.
1: <html> 2: <head> 3: <title>Craps applet</title> 4: </head> 5: <body> 6: <applet code="Craps.class" width=285 height=250> 7: </applet> 8: </body> 9: </html>
Most of the HTML tags on the page are just standard tags that are included on any
Web page. The width and height attributes of the <applet>
tag determine how big the applet will appear on a page. You can use any dimensions
and the applet will still run because Java creates programs that are flexible when
it comes to how they are displayed. For optimal appearance, however, use a width
of 285 and a height of 250.
In order to see the applet, you need to use a Web browser that can handle Java programs. At the time of this writing, the current versions of Netscape Navigator and Microsoft Internet Explorer cannot handle new features introduced in version 1.1 of the Java language. You have to use the appletviewer tool that comes with the Java Developer's Kit to test the Craps applet. If you're in the same directory as the Craps.asp file, the following command will cause appletviewer to load the applet:
appletviewer Craps.asp
Figure 22.1 shows the output of the Craps applet using appletviewer. Run the program several times to see the different ways that text and each of the dice can be displayed. Because the dice are drawn with polygons instead of by loading a picture of a die, the applet updates the graphics quickly as you play.
Figure 22.1. The Craps applet on a Web page viewed with the appletviewer tool.
The Craps applet that you have written shows how you can use Java to offer games on a Web site. The step-by-step process of creating a program was detailed, including some of the planning that occurs before you sit down at the computer. Because many of the program's tasks involved rolling or displaying dice, you created a special Die object to handle all of this functionality. Creating this object enables you to use some of the work you did for the Craps applet in other programs later on.
You can use this applet on a Web page in its completed form, and all that is required are the files Die.class and Craps.class and a Web page with HTML tags to load the applet. Thanks to the global reach of the World Wide Web and Java, you can bring the seedy charm of craps games to everyone from Afghanistan to Zambia, including Pia Zadora.
If you've become a gambler thanks to this hour's lesson, feel free to make wagers on your knowledge of programming before you answer the following questions.
Now that you have completed your most sophisticated Java project thus far, you can build your skills with the following activities: