CS21 Lab7: Top-Down Design

Due before 11:59pm, Tuesday Nov. 3

For this program you may work with one partner (you may not work in groups larger than two).

If you work with a partner:

The best way to work with a partner is to work together in the lab on all parts of the program together. You can work together on a copy of the code in one partner's cs21/labs/07 subdirectory and then email the file as an attachment to the other partner so that he/she can save a copy of your joint solution in his/her cs21/labs/07/ subdirectory too.

Starting Point Code
Run update21, if you haven't already, to create the cs21/labs/07. Then cd into your cs21/labs/07 directory and create the python programs for lab 7 in this directory (handin21 looks for your lab 7 assignments in your cs21/labs/07 directory):
$ cd cs21/labs/07
$ pwd
With the labs/07 directory is a file, phrasefile.txt, that contains a set of phrases that your program will use as input. You can, of course, add to this file or come up with your own files to use for testing.

Copying your labs/06 files over as a starting point:

Next, copy over your solutions from you labs/06 directory into your labs/07 directory, and move your guessconsonant.py to a file named wheeloffortune.py that you will use as the solution file for lab 7:
# from your labs/07 subdirectory:
$ cp ../06/* .
$ mv guessaconsonant.py wheeloffortune.py
Open, wheeloffortune.py in vim and copy into it your PrintMenu and GetMenuOption functions from your getmenuoption.py file. One way to do this is to:
  1. open wheeloffortune.py in vim
  2. go to the bottom of the file to the line right before the call to main() at the end of the file, and in command mode use enter the command:
    :r getmenuoption.py
    to read in the contents of the file getmenuoption.py at the current position of the cursor. Then edit wheeloffortune.py to remove all parts of getmenuoption.py except PrintMenu and GetMenuOption functions. Also, make sure that there is a single call to main() at the very end of your file.

Your programs are graded on both correctness and style. Please review the comments regarding programming style on the main page.

Wheel of Fortune
You are going to implement a single player version of the Wheel of Fortune TV game show. If you have never seen the show, here is some information on how it is played on TV. The rules for the single player game that we will implement are similar to, but slightly different from, the multi-player game on TV.

The single player rules:

Wheel of Fortune is a phrase guessing game where the player can guess letters in the phrase at each turn. At each turn, your program should:

The player takes multiple turns until either s/he wins by guessing the puzzle or s/he loses by spinning BANKRUPT or by giving an incorrect guess for the complete phrase. A each turn the player can:

    if the player spins:
    • A dollar amount (a random amount between $50 and $1,000 in 50 dollar increments):
      Then the player can guess a consonant in the phrase. If the consonant is in the phrase, then to the player's total earnings is added the dollar amount from the spin times the number of occurrences of the letter in the phrase (e.g. if the user spins $100 and guesses 't' and there are 3 t's in the phrase, the user gets $300 more added to his/her earnings).
      The part of the phrase guessed so far is updated for the next round, to show the correctly guessed letter.
    • BANKRUPT: the player loses all his/her earnings and loses the game.
  2. BUY A VOWEL: vowels cost $250 of a player's earnings. Subtract 250 from the player's total earnings (total earnings cannot be negative, so buying a vowel may not always be an option the player can choose), and the player enters a vowel. If the vowel is in the puzzle it is filled into the part of the phrase guessed so far. A vowel only costs $250 no matter how many times it appears in the phrase.
    If the player guess correctly, s/he wins the total earnings. If the player guesses incorrectly, s/he loses the game and earns nothing
  4. QUIT THE GAME: and forfeit all earnings
When the round of turns is over, your program should print out whether or not the player won, and if so how much his/her total earnings where, and print out the phrase.
Getting Started
You may want to start by looking at some of the sample output below to get an idea of what your program needs to do.

Then spend some time applying top-down-design to break the program up into parts that you can then code.

High-level first step of apply top-down-design:

  1. Print out the introduction to the player
  2. Get a random phrase from an input file of phrases
  3. Play the game
  4. Output the results: won or lost, amount won if won, and phrase
Each of these steps should be a separate function that is called from main (except the last step could be coded into main directly).

Next, iteratively refine steps (2) and (3) above, breaking them into sub-steps, and the sub-steps into sub-steps and so on until you have functionality that you can start testing. The PlayGame function, in particular should make calls to several other functions that implement pieces of the larger playing a game functionality. You already wrote some of the functions in lab 6, and you should use those functions and add new ones to this solution. As a point of reference, my solution has 15 different functions. Your solution doesn't need to have exactly 15, but if it only has 5, that is an indication that you have not broken down PlayGame into enough steps, where some of the medium-level sub-steps correspond to separate functions that are called in PlayGame.

Incrementally implement and test functions. Just like you did in lab 6, add some calls from main (or from PlayGame) to functions you write just to test them for correctness. Once you are satisfied that they work, then you can remove these test calls.

You can add just the shell of functions to test program control flow, and then fill in their implementation later. For example, I could implement just the following code, and run and test my program to see if I'm calling functions correctly:

def main():
  w = GetRandomPhrase()
  amt_won = PlayGame(w)
  if(amt_won == -1):
    print "You lost!!"
  print "You won $", amt_won

def Intro():
  print "The game rules"

def GetRandomPhrase():
  print "in GetRandomPhrase"
  return "hello there"
def PlayGame(phrase):
  print "in PlayGame phrase = ", phrase
  return -1
Next, I could start really implementing parts of these functions, maybe adding other function shells that they call to test incrementally.

As you implement and test incrementally, make sure that you keep in mind specific things that your program needs to do and refer back to the sample output if you are unsure about certain cases.

Here is a list of specific things your program must do:

Sample Output

Here is some sample output from different runs of a working program: Sample Output.

Notice the different ways in which a game can end, and how different types of errors are handled (including bad input values, not allowing the player to "buy a vowel" after s/he has already bought all of them, and not allowing a player with under $250 in earnings to buy a vowel).

Extra Extensions
These are NOT part of the regular assignment. Only attempt these after you have successfully completed the full regular assignment; an incorrect lab 7 assignment with extensions will receive a lower grade then a complete lab 7 assignment with no extensions.

Here are some ideas for extensions to lab 7 as an extra challenge: lab 7 extensions

Once you are satisfied with your programs, hand them in by typing handin21 at the unix prompt. You may run handin21 as many times as you like, and only the most recent submission will be recorded. This is useful if you realize after handing in some programs that you'd like to make a few more changes to them.