CS21 Lab 5: Fruitful functions

Due Saturday, Feb 29, before midnight

Goals

  • Work with functions and lists

  • Work with mutable and immutable function parameters

  • Understand function stack diagrams

Function Comments

All functions should have a top-level comment! Please see our function example page if you are confused about writing function comments.

Stack Diagram

The first part of the lab involves you tracing a program with functions and showing the resulting stack that the function calls generate. This is excellent practice for what will almost certainly be a quiz question! Download the PDF, print it out, and turn it in at the start of class Friday, February 28.

Wheel of Fortune

200

Wheel of Fortune is an American game show where contestants compete to guess a mystery phrase and win cash.

In this assignment, you will implement a simplified, single player version of wheel of fortune. The goal of the game is to win the most cash with the least number of turns to solve the puzzle.

At the beginning of the game:

  • the player starts with $0 dollars

  • a phrase is shown to the player with all letters hidden. Players can see spaces and punctuation

Each turn, the player can choose one of the following options:

  • spin the wheel: the player spins the wheel of fortune

    • If the player lands on cash, they may guess a letter. If the letter is in the phrase, they win (cash amount) * (number of letter in phrase).

    • If the player goes bankrupt, their total is reset to $0 and the game continues.

  • guess the phrase: the player can guess the phrase. If they are correct, they win the game. Otherwise, the game continues.

  • quit the game: the player can quit the game at any time. The answer is shown to the player when they quit

Below are sample playthroughs of the game:

We will build this program in steps!

1. askForLetter

In the file askForLetter.py, write a function askForLetter that asks the user for a character from a given subset.

Specification:

  • Parameters:

    • message (str): message to show user when asking for a letter

    • validChars (str): characters accepted by the function. If the user enters an invalid character, the function asks the user to try again.

  • Return (str): the character chosen by the user

  • Side effects: None

$ python3 askForLetter.py
Enter a consonant: 4
4 is not valid. Try again.
Enter a consonant: a
a is not valid. Try again.
Enter a consonant: w
You chose: w

Enter a vowel: w
w is not valid. Try again.
Enter a vowel: ^
^ is not valid. Try again.
Enter a vowel:
  is not valid. Try again.
Enter a vowel: o
You chose: o

Features:

  • You are given main() for testing. It calls your function twice

    • once to ask for a consonant

    • once to ask for a vowel

2. Working with puzzles

To manage puzzles, we will implement two functions:

  • initPuzzle

  • updatePuzzle

2.1. initPuzzle

In the file puzzle.py implement a function initPuzzle(answer) that takes a list of characters containing the answer and generates a puzzle (a new list) from the answer, but with all letters (a-z) replaced by "*", and all spaces replaced by "_".

Specification:

  • Parameter: answer (list): characters representing the phrase to guess, e.g. ["l", "o", "l"]

  • Return (list): characters with a-z characters hidden, e.g. ["*", "*", "*"]

  • Side effects: None

$ python3 puzzle.py
Answer:  i can't stop laughing
Puzzle:  *_***'*_****_********

$ python3 puzzle.py
Answer:  enough already
Puzzle:  ******_*******

$ python3 puzzle.py
Answer:  learning to speak another language
Puzzle:  ********_**_*****_*******_********

You are given starter code for main()

def main():
    answer = choosePhrase()
    print("Answer: ", makePhraseString(answer))

Features/Notes:

  • The function choosePhrase is defined in wheeloffortune_utils.py.

    """
    Purpose: Chooses a random phrase from the file "wheeloffortune.txt"
    Parameters: None
    Return (list): a phrase as a list of characters, ex. ["l", "o", "l"]
    """
  • The function makePhraseString is defined in wheeloffortune_utils.py. This function is useful for printing.

    """
    Purpose: Converts a list to a string
    Parameters (list): a phrase as a list of characters, ex. ["l", "o", "l"]
    Return (str): a phrase as a string, e.g. "lol"
    """
  • You only need to support lowercase letters

  • Letters should be replaced with "*"

  • Spaces should be replaced with "_"

  • Punctuation should be unchanged (see first example output!)

2.2. updatePuzzle

Implement a function updatePuzzle(puzzle, letter, answer) which updates a puzzle to show the given letter. If letter is not in answer, puzzle is unchanged.

Specification:

  • Parameters:

    • puzzle (list): the current state of the puzzle

    • letter (str): the character to update the puzzle with

    • answer (list): the answer to the puzzle

  • Return: None

  • Side effects: puzzle will be changed to show letter, if letter exists in the answer

$ python3 puzzle.py
Answer:  what up dawg?
Puzzle:  ****_**_****?

Enter a letter (type ENTER to quit): w
Puzzle:  w***_**_**w*?

Enter a letter (type ENTER to quit): x
Puzzle:  w***_**_**w*?

Enter a letter (type ENTER to quit): o
Puzzle:  w***_**_**w*?

Enter a letter (type ENTER to quit): #
Puzzle:  w***_**_**w*?

Enter a letter (type ENTER to quit): h
Puzzle:  wh**_**_**w*?

Enter a letter (type ENTER to quit): t
Puzzle:  wh*t_**_**w*?

Enter a letter (type ENTER to quit):
Puzzle:  wh*t_**_**w*?

Features:

  • Extend your program to use a while loop for testing updatePuzzle

  • When the user presses ENTER, input() returns the empty string (e.g. ""). Test for empty string to exit the loop

3. Game Time!

Now we implement our game in wheeloffortune.py. To start, copy the following functions into your file

3.1. main

The game loop should be implemented in main(). Below is the game loop algorithm.

answer = Choose a random phrase
Initialize the puzzle, the number of turns, the user's cash, and the done flag
Print welcome message

while not done:

    Ask the user if they want to spin wheel, guess the phrase, or quit
    If spin wheel:
        call spin wheel function
    Elif guess phrase:
        call guess phrase function
        if player guesses correctly, set done to True and print summary message about cash and turns
    Else:
        quit (e.g. set done to True)
    update number of turns

Print closing messages which include the answer to the puzzle

Build your program one function at a time. You can create stubs for functions you haven’t implemented yet. A stub can contain a single print statement or the pass statement. Test each function works before moving the next function. We will implement the following funtions in addition to main()

  • doSpinWheel(money, puzzle, answer)

  • doGuessPuzzle(answer)

3.2. doSpinWheel

Implement the function doSpinWheel(money, puzzle, answer)

Specification:

  • Parameters:

    • money (int): current total won by the player

    • puzzle (list): current puzzle state

    • answer (list): the answer

  • Return (int): the new total amount. $0 if the user goes bankrupt. Otherwise, the old total + cash won

  • Side effects:

    • phrase may be modified if player correctly guesses a letter

    • prints result of spin to console

Function features:

  • Use the function askForLetter to get a letter from the player

  • Use the function spinWheel defined in wheeloffortune_utils. This function returns either a dollar quantity or -1 if the player lands on bankrupt (example: cash = spinWheel())

    """
    Purpose: Spin the wheel of fortune
    Parameters: None
    Return (int): a positive value (cash value) or -1 (bankruptcy).
    Side effects: None
    """
  • If the wheel lands on a cash amount, ask the player for a letter

  • If the letter is already shown in the puzzle, print an error

  • If the letter is in answer but not already shown in the puzzle,

    • update the puzzle

    • calculate the cash won (formula: (cash amount) * (number of letter in the phrase)). Add the amount won to the player’s total

  • If the wheel lands on bankrupt, the player’s cash is reset to $0

Hints:

Sample output from running doSpinWheel

Test entering a letter. (In this example, if money was $100, the function would return $1300. Also, phrase will be changed to show the location of "t")

The wheel spins and lands on $600
Enter a letter: t
There are 2 of t in the phrase. You win 1200!

Test entering an already chosen letter. (In this example, if money was $100, the function would return $100. Phrase is unchanged.)

The wheel spins and lands on $600
Enter a letter: t
You already choose t!

Going bankrupt. (In this example, if money was $100, the function would return $0. Phrase is unchanged.)

The wheel spins and lands on BANKRUPT!

Letter not in phrase. (In this example, if money was $100, the function would return $100. Phrase is unchanged.)

The wheel spins and lands on $550
Enter a letter: x
x is not in phrase!

3.3. doGuessPuzzle

Implement the function doGuessPuzzle(answer)

Specification:

  • Parameters: answer (list): the answer

  • Return (bool): True if the player guesses correctly; False otherwise

  • Side effects: None

Features:

  • Function should ask user for the phrase and compare it to the answer

  • Return True if the phrase matches the answer

  • Return False if the phrase does not match the answer

3.4. Debugging tips

Try the following to make developing the game easier:

  • Show the answer when you initialize the puzzle. (Hide it again when you have everything working)

  • Create a small test file that has only a couple phrases. The default is to use wheeloffortune.txt. You can backup this file and replace it with a simple one having only 2-3 lines.

3.5. Extra Challenge: doBuyVowel

In wheel of fortune, the player only spins the wheel to choose a consonant. Vowels must be bought for $250 each. For this challenge, implement "buy a vowel" and modify doSpinWheel to only ask for a consonant.

A sample playthrough is here.

For this question, implement doBuyVowel(money, phrase, answer)

Specification:

  • Parameters:

    • money (int): current total won by the player

    • puzzle (list): current puzzle state

    • answer (list): the answer

  • Output (int): the new total after buying the vowel (e.g. total - 250 if total >= 250. otherwise unchanged)

  • Side effects:

    • phrase can be modified by player’s guessed letters

    • prints results of guess to console

Function features:

  • Use askForLetter to get a vowel from the player (cost is $250)

  • Use updatePhrase to update the phrase

  • Print an error if the player can’t afford to buy a vowel

  • If the vowel is already shown in the puzzle, print an error

  • If the vowel is in answer but not already shown in the puzzle, update the puzzle

Sample output from running doBuyVowel

Not enough money

You do not have enough money to buy a vowel!

Vowel in phrase

Enter a vowel: a
There are 2 of a in the phrase.

Vowel not in phrase

vowel u not in phrase!

Vowel already in phrase

You already picked a!