An Incremental Approach to Develop a Program When one has a large program to write, the easiest way to do it is via an incremental approach. So what we will do is develop and test this in pieces. That is to say, we will not write the whole program and test it out, but rather write a small piece, test it out, and when this piece works, add another piece until we have the entire program done. WHAT MUST main DO? So we look at "main", and start writing it. The method "main" is outlined to do 4 steps: (1) ask the user if they want to "play" a game? If the user says no, then terminate the program. (2) ask the user if they want the "rules". If the user replies yes, then call the method of "rules". (3) play the game by calling the method "play" of the object. If the user wins, call the method "play" again. Keep calling the method until the user loses the game. One knows if the user won or lost by the returned value of "play", which returns a true if the user won, false if the user lost. (4) thank the user for playing (via a System.out.println statement) and tell the user how many times they won the game before losing. IMPLEMENT STEPS (1) AND (2) OF main So what we do is first implement steps (1) and (2) above. These are done with if...then statements as we have done in Program3. To test it, we also write the method "rules", which is just a bunch of System.out.println statements as we did in Program1. After writing these parts, we compile and run the program. We then test the program out by giving all possibilities of responses and see if they work correctly. If there is a mistake, then we fix them. IMPLEMENT STEPS (3) AND (4) OF main Having implemented steps (1) and (2), we start working on steps (3) and (4). We write up the code for both of these steps. Step (4) is just one line. Step 3 is a simple loop with a call to method inside it as well as a counter to keep track of the number of wins. We then start working on the procedure "play", which is the hard part of the program. To simplify the development, we will again develop this in stages as well. Note that the complete development of "main" has now been done. That is why this approach is called "top down" as you work your way from the top ("main") down to the other procedures ("play" and then "rollDie"). TESTING STEP (3) OF main However, we want to make sure that it works correctly before we start working on "play". To do this, we put some code in "play" which we will remove once we are convinced that "main" works. One way to do this is as follows: Use "Math.random" to generate a number from 0 to 1. (We talked about "Math.random" in class.) If the number is greater than .75 return false, else return true. What this is saying is that the user is winning 3 out of 4 games. Then compile your program and run it. See if the output on the average states that the user won at least 2 games for several runs. Then change the number of winning to .8 (user wins 4 out of 5) and see if the average goes up. If this is the case, then "main" now works. Then go to "play" and remove the code involving "Math.random". You now should feel confident that "main" is correct. At this stage there is now no code inside of "play". START THINKING ABOUT CREATING play For "play", we first create the two die as indicated in the documentation of the program: Die dieOne = new Die(); Die dieTwo = new Die(); We then need to call "rollDie": result = rollDie(dieOne,twoDie); DEVELOPING AND TESTING rollDie So we postpone the rest of developing "play" by concentrating on developing and testing "rollDie". The procedure's protocol is: private int rollDie(Die one,Die two) We follow the development of this by following the discussion in the documentation. We roll each die (one.roll() and two.roll()) and get the results of each via getNumber for each object. (The getNumber is similar to the scan.nextInt() that you used in Program2 in that it returns an integer value.) We add up the results (as we did in Program2) and return that value (as we did in Program4). This can be done in 6 lines of code. Now, we must test whether the "rollDie" method works. There are several ways to test it. One way is to call "rollDie" 36 times and print out the result of each call to the console window. (Note to call it 36 times a for loop would be a good construct here.) Then return false after exiting the loop. The reason we return false to main is to terminate the program. We call "rollDie" 36 times because of the way that one "expects" a fair roll of the dice to happen. I.e., if one rolls a fair pair of die 36 times, one expects to get a total of 2 and 12 once, 3 and 11 twice, 4 and 10 three times, 5 and 9 four times, 6 and 8 five times, and 7 six times. So compile and run the program and count the number of times each value appeared. Do this for a few runs and see what the distribution of the values that "rollDie" returned. If one gets the a fair approximation to the distribution (one will rarely get the exact distribution), then one knows that "rollDie" works. Then remove the loop and the return false statement from plays. Then we will now finish off the development of plays as discussed in the documentation. START DEVELOPING play BY DOING THE FIRST TOSS If the game is won or lost on the first throw, the user is notified of what the result of the die was and whether (s)he won or lost via System.out.println. A boolean value is returned by the method (true if the user has won, and false if the user lost). So the method terminates with the returned boolean value. If the game is not won or lost on the first throw, the value of point is set to the result and the user is notified of the point they are trying to win with (again via a System.out.println). (Note that point is a local variable inside of "play".) To test whether the first throw is done correctly, you should return a value of "true" if the game is NOT won or lost on the first throw. This is because then the game will be replayed from "main", and you will have further testing of "play". Once you have determined that the method of "play" correctly handles the first toss, you can start working on the rest of the method. FINISH DEVELOPMENT OF play If the game is not decided on the first throw, then the value of the variable point has been set to the value of the first throw (a value of either 4, 5, 6, 8, 9, or 10). Then a while loop is entered and one continues to roll the die until the game is won or lost. The user is notified of the outcome of each roll of the die (again via a System.out.println). This must be inside the loop. Before returning, the user is notified if they won or lost. It will then return true if the user won and false if the user lost. Then you now have the complete program. Of course, you must test the program to see that it works. Note that you can easily get into an "infinite loop" while developing the program. You know that you have an "infinite loop" if your program does not terminate in 10 seconds. In BlueJ, you terminate the program by RIGHT clicking on the horizontal red and white barber pole at the lower left hand corner of the BlueJ window. A box will open on and then left click on this box. However, if your program is not working, you know that the problem is only in the "plays" module and the System.out.println will tell you what is not working. This should make the debugging relatively easy. If you have an infinite loop, then use the debugger as shown in class to walk through the program line by line to see where it occurs. Note that it might not always occur for some runnings.