Radford University ITEC

ITEC120-ibarland (incl. office hrs)infolectureslabshws

practicing loops:
Amy and Bob flip coins

Oct.18 (Wed.): For this lab, you may work individually or with a partner. Check off your work before you leave lab, or at the start of lab on Friday. (If you don't check off the program today, make sure you and your partner each have a copy of your work.)

Amy and Bob each have a coin, and each start with 50 jellybeans. A single turn consists of each of them tossing the coin:

They take turns repeatedly, until one of them runs out of jellybeans. (They have strong willpower, and don't eat any jellybeans until the game is over.)

Download (and save-to-your-H:-drive) the Coin and Die classes, and then open it from BlueJ via Project > Open non-BlueJ…. (Don't have the computer automatically open the file upon downloading; it will open it with something besides BlueJ. If you have trouble opening this .jar file, you can open each class separately: Coin.java, Die.java.) You won't need to modify either of these files, but you will need to look at the interface of Coin, so that you know what methods it has. (You won't even use Die.java, however Coin.java uses it.)

  1. Create a class JellyBeanGame, with two fields — Amy's coin, and Bob's coin.
  2. Write a method takeOneTurn, which flips each coin once and returns +1 (if Amy wins), -1 (if Bob wins), or 0 (if they tie). Be sure to test this method before proceeding. Be sure to not toss either coin more than once!
  3. Write a method playOneGame which has local variables representing each player's number of jellybeans, as well as the number of turns-so-far. playOneGame repeatedly takes turns (keeping track of each player's number of jellybeans), until somebody runs out. (Note that whatever is added to Amy's score — whether positive or negative — is subtracted from Bob's.)

    Once the game is over, playOneGame will do two things:

    1. Print a message on the console window, saying who won and how many turns it took. For example, "Congratulations to Bob, who won after 217 turns." might be printed.
    2. Return the number of turns required (for example, 217 might be returned).

  4. Optional: Create a second (overloaded) version of playOneGame which takes in a parameter: the number of jellybeans to use initially. Don't repeat any code — one of these two versions should call the other!

    More jellybeans tends to mean longer games. Can you quantify this effect? (That is, does twice as many jelly-beans mean games which are twice as long, on average? Ten times as long? 1.5 times as long?)

  5. Optional: Discuss: It isn't absolutely necessary to keep track of both Amy's and Bob's #jellybeans; if you keep track of just (say) Amy's score, how can you compute what Bob's score is? Is it preferable to keep track of just one score? Do you consider this a tension between two laws of programming: “Single point-of-control” vs. “Have your program reflect your conception of the real-world situation”?

Things needed for a check-plus:

Solution


Oct.20 (Fri.)

Amy and Bob have noticed that some games take more turns than others.

  1. Add a method to your program which plays 100 games, and returns the average number of turns taken. (Remember: you compute the average by adding up the total number of turns taken across all 100 games, and divides by the number of games.)
    Remember, no magic number; use a named constant instead!
    You may use a while loop, or (if you prefer), a for loop as discussed in Chapter 5.

    Solution

  2. Note that since Java will do integer-division (unless you cast the numerator/denominator to doubles), we aren't quite getting real division. How serious is this, in this case? Can you quantify your answer, like “well yes, there is some error, but it is guaranteed less than …%.”? (Imagine that your boss is asking this question, and you need to either defend the use of integer division, or change your program so that the results aren't bogus.)
  3. Reflect: when we wanted to call playOneGame many times, how helpful was it, that the method printed messages to the screen? How helpful was it, that the method returned an int?
  4. Optional food for thought:
    Some people have wanted to return two results from playOneGame -- both the length of the game, and the winner. Others wanted to return even more bits of information (say, the highest balance ever achieved by the losing player, or the number of ties that took place, or …). Java — and most (but not all) programming languages — are limited by the fact that a function/method can only return one single value. So what do we do when we want to convey several pieces of information?
    We make a single class, which contains the information as fields. In this case, a class GameStats might have fields winner, numTies, lengthOfGame, etc.. In this way, we hack around the language's limitation, and are effectively returning multiple values.
We won't check off this week's lab (taking attendence only), but writing the code for #1 above, given the code for Wednesday's lab, is something which would be fair game on an exam, so you should understand how to do it.


Extra Credit

(to be done individually; the equivalent of one lab; accepted up through Nov.12 (Mon)):

  1. Modify this function which computes averages, so that it takes in an argument: the initial number of beans for each player (instead of always using 50).
    This entails going back and changing playOneGame to accept the initial number of jellybeans as an argument (one of the optional bits from above).
  2. Now, write a method which computes the average of games based on i initial jellybeans, where i starts at 1 and successively doubles (1, 2, 4, 8, 16, …) up to 256 (you can set this limit smaller, if your program takes too long to finish, and/or for testing). The method should return one big String reporting all your results, something similar to:
    Starting with 1     jellybean  takes approx. 2     turns (a sampled average).
    Starting with 2     jellybeans takes approx. 5     turns (a sampled average).
    Starting with 4     jellybeans takes approx. 34    turns (a sampled average).
    
    
    (Use \t to embed tabs in a String; to see what the String looks like when printed, you can call System.out.println from BlueJ's codepane. If your average is a double, and you want to display it nicely, look up class DecimalFormat in the book's Section 3.6.)
  3. By hand, or by program: What is the ratio between successive numbers in your table? (That is, 33/5 and 5/2, in this example.) Do these successive ratios seem to converge to a particular number?

    Math aside, optional: Polynomials have the property that doubling inputs makes the output go up by (roughly) a constant factor; the bigger the input, the less rough this is. For example, if f(x)=5x3-x, then f(2x)= 5(2x)3-2x = 40x3-2x; as x gets larger, the ratio f(2x)/f(x) approaches 40/5=8=23. That is, doubling large inputs will octuple the output, which is the sign of being essentially a 3rd-degree polynomial.
    Your question: Does the average length of our coin-game seem to be essentially polynomial (as a function of the number of initial jellybeans)? If so, of what degree?

ITEC120-ibarland (incl. office hrs)infolectureslabshws


©2006, Ian Barland, Radford University
Last modified 2006.Oct.20 (Fri)
Please mail any suggestions
(incl. typos, broken links)
to ibarlandradford.edu
Powered by PLT Scheme