CPSC 124 (Fall 1998): Lab 7
Arrays of Objects
WELCOME TO THE SEVENTH LAB for Computer Science 124. In this lab, you will work with arrays in two applets. The first exercise is a third, and final, version of the bouncing balls applet. By using an array of balls, you can easily work with a much larger number of balls than in the previous versions. In the second exercise, you will work with an array of playing cards.
Before you begin, copy the folder /home/cs124/lab7 into your home directory.
The exercises at the end of the lab are due in class on the Monday following the lab.
Outline of the Lab
Bouncing Balls: The Final Episode
In your first "bouncing balls" exercise, in Lab 3, you added bouncing balls to an applet by cutting, pasting, and editing several variable and subroutine declarations -- a tiresome and error-prone task. In the second exercise, in Lab 5, you were able to create a BouncingBall object with a single line of code, and you could easily manipulate the object by sending messages to it. However, it would still be tiresome and difficult to work with a large number of balls in this way. In this lab, you will use an array of BouncingBall objects. This will let you easily use as many balls as you want, within the limits of the computer's ability to draw the frames of the animation in a reasonable amount of time.
You should copy your own BouncingBallsApplet.java from your lab5 directory to your lab7 directory. Rename the file to BouncingBallsApplet3.java, and rename the class to BouncingBallsApplet3. The lab7 directory already contains copies of the supporting files BouncingBall.class and SimpleAnimationApplet.class. It also contains an HTML file, bounce3.html, for running the applet. Before you write your own version of the applet, you can see my version by saying ``appletviewer bounce3.html''. You can also see the applet here, on a separate page.
Start by adding a constant to the applet to represent the number of balls. Set the constant equal to 25 (or to some other value that you think will produce a nice result):static final int ballCount = 25;
Also add an array variable to hold a list of BouncingBall objects:BouncingBall balls;
Recall that this only creates a variable that can refer to an array. You still have to create the actual array and then create the objects that go into the array. This should be done in the applet's init() method, since you only want to do it once, when the applet is first created. If you wanted to create an array of red balls with radius 10, you would use the following commands in the init() method:balls = new BouncingBall[ballCount]; for (int i = 0; i < ballCount; i++) balls[i] = new BouncingBall(Color.red,w/2,h/2,10);
However, you should create balls of different colors and possibly differing radii. In my applet, I use randomly generated colors for the balls. A random color can be generated by using a random integer between 0 and 255, (int)(256*Math.random()), for the each of the three color components of the color.
Once you've generated the balls, you can modify the drawFrame() and mouseDragged() methods to use the array. Your applet must work properly even if you change the value of the constant, ballCount, and recompile the applet.
A Simple Card Game
In the second exercise of the lab, you will use an array of Cards, where Card is a class that represents a playing card. The Card class is defined in the file Card.java. You might be interested to look at how arrays are used in this file to hold the names of the suits and values. This makes it very easy to convert the code number of a suit or value into a string. You will also use the class Deck, which is defined in the file Deck.java. This class uses an array of 52 card objects to represent a deck of playing cards.
The applet you will work with is a simple card game: One card is dealt at a time, and the user tries to guess whether the next card dealt will be higher or lower in value than the current card. A completed version of the applet can be found on a separate page.
Your lab7 folder contains an incomplete version of the applet. You can run it with the command "appletviewer cards.html". In this version, all that happens is that when you press any of the buttons, a new card is dealt and the canvas where the cards are displayed is redrawn. Your assignment is to complete the applet. The file HighLow.java defines two classes: the main applet class, HighLow, and a canvas class, HighLowCanvas, that is used by the applet. The applet class merely lays out the applet. All the actual work is done in the canvas class. The changes that you will make for this exercise all go in the HighLowCanvas class. You do not need to change the applet class at all.
Add an array variable, "Card cards;", to the HighLowCanvas class. You will also need an int variable, cardCount, to keep track of how many cards have been shown so far. In the constructor of the class, create the actual array with the statement "cards = new Card;".
The applet already has an instance variable named message, of type String. This string is drawn by the paint() method at the top of the canvas. Whenever you want to change the displayed message, you should change the value of the variable, message, and call repaint(). By doing things this way -- rather than simply drawing your message directly onto the applet -- you ensure that the message can always be properly redrawn by the paint() method when necessary. The variable, message, is part of the state of the applet. The usual rule is: If you want to change the display, change the state and call repaint().
The applet also has a boolean instance variable named gameOver. This is an important variable that keeps track of the main state of the applet. If gameOver is true, then it is not legal for the user to click on the "Higher" or "Lower" button. You should ignore such clicks, and maybe display an error message. If gameOver is false, then it is not legal for the user to click on the "New Game" button. You should ignore such clicks, and maybe display an error message. You should be careful to change the value of the gameOver variable when the state of the game changes, that is when the game ends and when a new game starts!
Modify the paint() method so that it will draw all the cards that have been shown so far, using the values of the cardCount variable and the cards array. (You do not necessarily have to draw a face down card, as I did. On the other hand, you might want to fill all the extra, empty spaces with face-down cards.)
Modify the actionPerformed() method so that it calls a different method, depending on whether the user clicks on the "Higher" button, the "Lower" button, or the "New Game" button. For the "New Game" button, you can call the existing startGame() method.
Modify the startGame() method so that it deals the first card into the first position of the array, cards, and sets cardCount equal to 1.
Write one or two methods to handle the "Higher" and "Lower" buttons. (You can write a separate method for each button, or write one method with a parameter to tell it which button was pressed.) The game ends if the user guesses wrong, and in that case the user loses. Display a message to that effect (and don't forget to set the value of the gameOver variable). The game also ends if the six cards have been dealt without any wrong guesses, and in that case the user wins. Again, you should display an appropriate message if that happens.
(By the way, this applet does a bit of fancy stuff with image display to get the cards on the screen. You don't have to understand how that part of the program works.)
Extra Credit Opportunity
This part of the lab is for extra credit. You can do it if you want.
Once you've completed the previous section of the lab, you have a working game, but it violates one of the rules of good GUI design: The state of a program should be reflected in the state of the GUI. In particular, when it is illegal for the user to click on a button, that button should be disabled. A disabled button is non-functional, and its appearance is changed so the user can see that it is non-functional. In Java, if bttn is a button, it can be disabled with the statement "bttn.setEnabled(false);" and enabled with the statement "bttn.setEnabled(true);". Of course, this requires extra work on the part of the programmer, but it makes for a cleaner GUI design.
You can see an improved version of the HighLow applet with "appletviewer cards2.html". You can also see it here on a separate page. In addition to enabling and disabling buttons in this version, I changed the color scheme and I uses a GridLayout for the bottom Panel, which holds the buttons. (A GridLayout divides a container into equal-sized rectangles. The command "bottom.setLayout(new GridLayout(1,0));" tells the panel to use a grid layout with one row and any number of columns. That is, all the buttons added to bottom will be arranged into one row, and all the buttons will be of the same size.)
Now, if you want to be able to enable and disable buttons, you need instance variables to refer to those buttons. In the HighLow applet, where all the work is done in the HighLowCanvas class, those instance variables must be in the HighLowCanvas class. So, you should move the declarations of the three buttons from the init() method of the HighLow class into the HighLowCanvas class. Create the Button objects in the constructor of the HighLowCanvas class. Back in the init() method of the HighLow class, you will still have to refer to the buttons so that you can add them to the bottom panel. You can refer to them as members of the canvas. For example, the newGameBttn variable in the canvas would be referred to as canvas.newGameBttn.
Once you've got the buttons properly moved to the HighLowCanvas class, you can enable and disable them as appropriate, whenever a game starts or ends.
Exercise 1. (8 points) Turn in a printout of your bouncing ball applet. Also, post the working applet on the web and put a link to it on your home page.
Exercise 2. (10 points) Turn in a printout of your HighLow card game. Also, post the working applet on the web and put a link to it on your home page. You can get five points of extra credit by writing an applet in which the buttons are enabled and disabled to reflect the state of the game.
Exercise 3. (7 points) Write a short essay discussing arrays, how they were used in this lab, and why they are essential in many interesting programs.