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
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 inwheeloffortune_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 inwheeloffortune_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
-
menu
from assignment 4 -
alldigits
from assignment 4 -
askForLetter
-
initPuzzle
-
updatePuzzle
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:
-
The string module contains a function
count
for counting the occurances of a letter in a string. Click here for examples of how to use count() -
The 'in' keyword can be used to check if a letter is contained in a list Click here for examples of how to use
in
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!