Winning it BIG in the Lottery

Copyright RIT 2003
$Id: writeup.xml,v 1.6 2003/10/07 18:43:37 cs1 Exp $


Goal

The primary purpose of this lab is to give you a chance to work with conditional statements and loops. To do this you will complete the implementation of a simple Lotto game. Along the way you will have a chance to learn a little bit about event-driven programming and the model-view-controller design model.

You will be working with a program that implements a Lotto game, similar to the QuickDraw game run by the New York State Lottery. In this version of the game the player must select the 6 numbers out of 49 that will be selected by the computer. The game maintains a set of statistics so that the player can see how much, or more likely, how little money they will be winning.


Team Setup

You are to work on this lab completely on your own.

Overview

Objectives

Ask Dr. Tiger

Background

Over the years experienced programmers tend to use the same techniques to solve similar problems. Only recently have attempts been made to catalog some of the more common approaches to these problems. These approaches are commonly referred to as design patterns. A design pattern names and explains important and recurring designs in object-oriented systems. One such pattern, that is commonly used in Graphical User Interfaces (GUI), is the model-view-controller (MVC) design pattern. In this pattern, the program is logically divided into three objects: model, view, and the controller. The model is the application, the view provides a visual representation of the model, and the controller defines the way the user interface reacts to user input. The MVC pattern is illustrated in Figure 1.


Figure 1

The main motivation for the MVC pattern is to separate the logic of the program from its view. In this way, if someone decides to change the graphical user interface, the only component that needs to be modified is the view. It is also possible to have multiple views that use the same model.

In this lab, you will be working with a program that consists of four classes: Lotto, LottoGUI, LottoLogic, and BallBox. The LottoGUI class does the work of the view and the controller from the MVC model, and LottoLogic does the work of the model. BallBox is a class that provides the ability to generate a stream of random numbers. Figure 2 illustrates how these classes interact to make up the Lotto program. For those of you who are interested in building simple GUI based applications, LottoGUI contains most of the basic code that you will need to develop a GUI on your own.


Figure 2 Figure 2

Programs that use graphical interfaces are not controlled in the same way as a standard program. The part of the program that is in control is the GUI. The GUI generates events that trigger the appropriate action within a model. For example in the lotto program, when the GUI senses that a user has pressed a numbered button, it will call the buttonPressed() method in a LottoLogic object. So the Lotto program does not determine when buttonPressed() is invoked, the user does. The Lotto program is driven by events external to the program as opposed to by logic within the main program. This type of programming is referred to as event-driven programming.

The LottoLogic class contains three methods that are meant to be called by the GUI in response to external events. These methods are: draw, reset, and buttonPressed. Your task in this lab is to complete these three

Pre - Lab Work

  1. Review your class notes for the preceding week.

  2. Complete the conditional statement exercises found by clicking here (/~cs1/Exercises/_Conditionals) .

  3. Read this lab's background information on Model/View/Controller designs (background.html) .

In-Lab Activities

Activity #1 : Play the Lottery!

Download a copy of the jar file (/~cs1/pub/lab06/lab6.jar) that contains the files you need to complete this lab and unpack it in the subdirectory you created for your CS1 lab work.

In order to get a feel for how this program fits together, you will write it in several stages. At the end you should have a working Lotto game. Before we get started though, take a couple of minutes to play the working version of the game. From a Unix prompt execute the following command:

~cs1/pub/Labs/06/runlotto

If everything worked correctly you should see the lotto screen displayed on your terminal. Before you can play the game you must select 6 lucky numbers. You select a number by clicking on the numbered button that contains the number you want. When you select a number the button should turn blue. You can unselect a number by clicking on it a second time. Once you have your numbers selected, cross your fingers, and click the draw button. The computer will select 6 numbers at random and display them on the board. If you and the computer selected the same number, the corresponding numbered button will turn yellow. Any numbers the computer selected, that you did not, will turn green. You can click the draw button as many times as you wish. Feel free to change your lucky numbers if they turn out not to be all that lucky. The game maintains statistics that let you see how well you are doing.

There are two other buttons on the interface that were not described above. Take a few minutes to figure out what they do. The names of the buttons should give you a good idea of what the buttons do.

Keep in mind that this version of the program is a sort of combination of the versions of the games you will write. It is not exactly the same as any single one of them.

Your first task is to familiarize yourself with the javadoc for the Lotto Program (docs/index.html) . The file Lotto.java simply starts up the program. BallBox.java is used to generate the random numbers the computer will draw for the user. You will not need to change this code, but you should understand how to use it.

The interesting classes in the Lotto program are the ones contained in the files: LottoGUI.java and LottoLogic.java. The LottoGUI class creates, and manages the GUI for the program. Take a few minutes to look at the documentation for this class. You will be modifying the LottoLogic class which implements the logic of the game in activities 2 - 5. For now familiarize yourself with the LottoLogic class and find the three methods that you must complete (draw, reset, and buttonPressed).

You received a questions.txt file when you downloaded the files for this lab. Use emacs to edit the file and replace the phrases YOUR_ANSWER_HERE with the answers to each question.

How To Submit

When you are done, save your file and submit it using the following command:

try cs1-grd lab6-1 questions.txt

Activity #2 : Experiment with event-driven programming

The next step is to get a feel for how event driven programming works. A LottoGUI object will invoke the draw(), reset(), and buttonPressed() methods in a LottoLogic object when the user presses the corresponding buttons on the GUI. A simple technique that can be used to determine when a method is invoked, is to place a simple print statement inside the method. This way whenever the method is invoked the print statement will be executed.

Use emacs to edit the LottoLogic.java file and find the draw() method. Inside the draw() method add the following line of code:

System.out.println( "draw() was called" );

Now compile the program (javac *.java should do the trick), run it (java Lotto), and press the draw button. Every time you press the draw button you should see the message:

draw() was called

appear in the terminal window from which you started the Lotto.java program. Note that the only time your program produces output is when the draw button is pressed. Pressing the draw button triggers an event in LottoGUI, which in turn calls the draw() method. This is how event driven programming works.

Next add a print statement to the reset() method so that when the reset button is pressed the message

reset() was called

will appear.

Now add a print statement to the buttonPressed() method so the following message will appear when the method is invoked.

buttonPressed() was called

Compile and run the program and verify that the reset and numbered buttons cause the appropriate actions to take place.

Now quit the program and make another simple modification. Change the print statement in buttonPressed() so that the number of the button that was pressed is printed out along with your original message. (The documentation for buttonPressed() (docs/LottoLogic.html#buttonPressed(int)) will tell you how to get the label of the button that was pressed). The message should now look like this when the buttonPressed method is executed after the user presses the number 48:

buttonPressed() was called: 48

Compile the program and run, it several times. Continue doing experiments such as this until you understand how the event driven programming model works.

How To Submit

Once you are sure that you understand how event driven programming works, submit your work by executing the following command:

try cs1-grd lab6-2 LottoLogic.java

Activity #3 : Selecting Numbers

Before working on the methods that are in the LottoLogic class, take a few minutes to familiarize yourself with the data members of the class. The first four data members of the class are constants that define some basic attributes of the game. The constants NUM_ROWS and NUM_COLS define the number of rows and columns in the numbered button portion of the display. The constant MAX_NUMBER defines the maximum number displayed by the GUI. The last constant MAX_SELECT defines how many numbers the user must select before making a draw.

The data member gui is a reference to the LottoGUI object that is displaying the current game. You will use this reference to invoke methods that will change the appearance of the GUI. The box data member holds a reference to the BallBox object that will be used to generate the the numbers the computer will guess. Finally, the data member numButtonsPressed keeps track of the number of buttons the user has selected. You do not need to worry about initializing these variables since the constructor for this class has already been written for you.

Now let's get some real work done. We will start by replacing the print statement that was placed in the buttonPressed() method with the code required to select a button and turn it blue when it is clicked by the user. In order to do this you will have to understand the methods that LottoGUI provides to you. Click the following link to view the documentation for the LottoGUI class. You should see a method named setSelected() which allows you to mark a button as selected, and setButtonColor() which allows you to change the color of a button. Note that setButtonColor() takes a color in addition to the button number to change. The button number is easy to figure out, but what about the color? Java provides a class called Color that is used to represent the various colors that can be displayed on a screen. Take a few minutes to look over the documentation for the Color class by clicking here (http://www.cs.rit.edu/usr/local/jdk/docs/api/java/awt/Color.html) . Based on this information, the statements required to select a button and change its color to blue are:

gui.setSelected( button, true );
gui.setButtonColor( button, Color.blue );

Since we want these statements executed whenever the user presses a numbered button, place them in the buttonPressed() method in the LottoLogic class, compile, and then run the program. If you did things correctly the numbered buttons should now turn blue when you press them. Things are getting better, but notice that once you select a button you cannot unselect it.

Turning a button back to its original color (which is Color.lightGray) is not hard, but how do you know which color to change a button to when it is pressed? The answer is to check to see if the button that was clicked is selected or not. If it is not selected, select it and change the color to blue. Otherwise unselect it and change the color to light gray. Modify the code so that the user may unselect a button. Once you have finished making your changes, compile and run your program to verify that the changes are correct.

At this point your program allows you to select and unselect numbers, but surely you have noticed that the user may select as many buttons as they wish. The last thing that you need to figure out is how to limit the number of buttons selected to six. This could be done by adding a data member to the class that keeps track of the number of buttons that have been selected. If six buttons have been pressed, and the user presses a seventh button, the code can simply refuse to select another button.

You may have noticed when you first started looking at the LottoLogic class that there was a data member named numButtonsPressed declared at the beginning of the class. Make one last modification to buttonPressed so that the user is only allowed to select at most six numbers (use numButtonsPressed to keep track of the number of buttons pressed, and the constant MAX_SELECT to determine the maximum number of buttons the user may select). Make sure that you make the changes required to update numButtonsPressed when a user selects and unselects buttons.

Compile your program and verify that it handles the selection/unselection of numbered buttons. Remove the print statements from the buttonPressed method, compile your program, and verify that it is still working correctly.

How To Submit

Please note that, for this and all future submissions of the LottoLogic.java file, all the "instrumentation" printing statements you added in the previous activity should have been removed. The only text output you should see in your shell from running the program should be the two startup lines that were there from the beginning.

When you are sure that your program is working correctly, submit it using the following command:

try cs1-grd lab6-3 LottoLogic.java

Activity #4 : Drawing numbers

Now that the user can select their lucky numbers it is time to write the code to draw the numbers. The draw() method will be called by LottoGUI whenever the user presses the draw button, so that is the method that you will work on in this activity.

A draw cannot take place in this game until the user has picked six numbers. It is not hard to write the code to do this since you know about conditional statements and you know about the data member numButtonsPressed. Start this activity by changing the code in the draw routine so that the print statement you placed in the draw() method, is printed only if six numbers have been selected. Compile and run your program to verify that it is doing what you expect.

The first thing that the draw() method needs to do, if MAX_SELECT numbers (six) have been selected, is to clear the board so that the computer can display the results of the draw. The method clearTheBoard(), which has already been written for you, takes care of preparing the board for a new draw. Replace the print statement in your draw() method with a call to the clearTheBoard() method. Compile and run your program to make sure that things are working correctly so far.

Now you need to write a loop that will draw six numbers from the ball box. Take another look at the documentation for BallBox to make sure that you understand how to draw the numbers (note that you do not need to invoke refill() on the BallBox since that has already be done by the clearTheBoard() method). Write a loop that will draw the appropriate number of numbers and print the numbers on the screen as they are drawn. Compile and run your program to make sure your changes work correctly.

Now for the colors. As your loop draws numbers it needs to change the color of the buttons so that the user can tell whether or not they won. If a drawn number matches one of the numbers selected by the user, the button should be colored yellow. If the number drawn does not match, the corresponding button should be colored green. Replace the print statement in your draw() method so that the colors change on the GUI as the balls are drawn. After making the changes, compile and run your code to verify that things are working correctly.

Make sure that the draw() routine you wrote operates correctly before going on to the last activity. Don't worry about the statistics, yet!! That will be taken care of in the next activity.

How To Submit

When you are sure that your code is working correctly, submit it using the following command:

try cs1-grd lab6-4 LottoLogic.java

Activity #5 : Putting it all together

Now the code that updates the statistics after each draw needs to be added. After a draw, two counters need to be updated, the total number of draws, and a number that keeps track of how many numbers the user got right. The LottoGUI class contains methods that can be used to update each of the statistics. Take a look at those methods and then add the code required to update the statistics after each draw to your program. Compile and run your program and verify that the statistics are now being updated.

The last thing you need to do in this activity, is to write the code that gets executed when the user presses the reset button. By now you should realize that the code required to do this needs to go in the reset() method. From your earlier experiments in activity 1 (activity1.html) you know that when the reset button is pressed, the board is cleared (of the winning numbers from the last draw) and the totals are reset back to zero. You should also have noticed that numbers choosen by the user are not cleared. Replace the print statement you placed in the reset() method with the code required to clear the board and reset the totals. Make sure you test your program and verify that it works correctly.

How To Submit

After you are convinced that your program is correct, submit it using the following command:

try cs1-grd lab6-5 LottoLogic.java

Post-Lab Activity : Buying coffee

The Java Coffee Outlet sells only one type of coffee beans harvested exclusively in the remote area of Irian Jaya. The company sells the coffee in 2-lb bags only, and the price of a single 2-lb bag is $5.50. Discounts are given to volume buyers. The discount is based on the following table:

Order Volume Discount
more than 25 bags 5% of the total price
more than 50 bags 10% of the total price
more than 100 bags 15% of the total price
more than 150 bags 20% of the total price
more than 200 bags 25% of the total price
more than 300 bags 30% of the total price

Write a program that accepts the number of bags ordered and prints out the total cost of the order. Use RitIo to get the number of bags for an order from the user. You should first use ask the user how many bags they wish to order using the prompt:

Number of Bags Ordered: 

There should be one space after the ":" and a blank line after the prompt. The output from the execution of your program should be identical to the output shown below when input from the user is the same.

Number of Bags Ordered: 173

Number of Bags Ordered: 173
Total Cost: $951.50
Less 20% Discount: $190.30


Your total charge is: $761.20

Note that the first line of output shown above is the prompt and response from the user (173). You should also notice that the output contains a blank line before repeating the label that was the prompt for input along with echoing the response from the user (the number of bags ordered). There is a single space after each of the ":" characters in the output. There are two blank lines before the "Your total charge is:" line.

It is okay if the decimal numbers in your output do not match the format shown above as your program will probably not display the same number of decimal places as the example.

Place your program in a file named Coffee.java.

How To Submit

Once you are convinced that your program is working correctly, submit it using the following command:

try cs1-grd lab6-6 Coffee.java


Grade Computation

Grade Breakdown: