For this assignment, you will be implementing a text-based version of hangman. There are many variants of the program, so follow the specifications closely. Make sure that you read through this whole handout first before getting started. We've given an overview of how to proceed and then some hints near the end.
For this assignment, we will use a dataset stored as a list of tuples. Our collection will be a list of movies along with information about those movies. To obtain the list of films, download the assignment 5 starter file. It will contain two files, movies.txt
and movies.py
. The text file is a "delimiter-separated values" file which we'll write a little bit of Python code to read into our list of tuples. Make a assignment5
folder and place movies.txt
and movies.py
inside of it.
Open up movies.txt
and take a look at the format. Note that each line has the same number of vertical bars, and try to get a feel for the format. Our first task is to implement the get_movies
function in movies.py
to read in this file and load our movie database.
You can take a look at get_practice_movies
to get a sense of what the Python data structures we want should look like:
>>> practice = get_practice_movies() >>> practice[0] ('jaws', 'A big shark eats stuff', 1975)
Each movie should be a tuple like the ones coming out of get_practice_movies
: The lowercased title, a description, and an integer year. You can use the string split
and lower
methods to help you out here. You may also get some use out of rstrip
.
Completing get_movies
is worth 4 points.
Once you're happy with get_movies
, it's time to implement the game itself in a new file hangman.py
. The program should randomly pick a film (using Python's random module) and give the user some information about the movie to help them guess:
*** Movie Hangman *** Year: 1997 A deranged media mogul is staging international incidents to pit the world's superpowers against each other. Now 007 must take on this evil mastermind in an adrenaline-charged battle to end his reign of terror and prevent global pandemonium.
After this has been displayed, the program should then display the general hangman output:
___________________ Guessed letters: Movie: -------- ----- ---- Guess a letter:
This display has two main components:
The following transcript shows these different situations happening as the game is being played:
___________________ Guessed letters: Movie: - - - - - - - - - - - - - - - - - Guess a letter: e ___________________ Guessed letters: E Movie: - - - - - - - - - E - E - - - E - Guess a letter: s ___________________ Guessed letters: E S Movie: - - - - - - - - - E - E - - - E S Guess a letter: a ___________________ Guessed letters: A E S Movie: - - - - - - - - - E - E - - - E S Guess a letter:
In the first two guesses the letter was in the movie, but in the third it was not.
The game ends when the user fills in all of the dashes in the word. The movie is displayed along with the number of guesses that it took the user. For example, here are the last two guesses and the winning output:
___________________ Guessed letters: A E I M N O R S T V Movie: T O M O R R O - N E V E R - I E S Guess a letter: w ___________________ Guessed letters: A E I M N O R S T V W Movie: T O M O R R O W N E V E R - I E S Guess a letter: d ___________________ You win! The movie was: tomorrow never dies You guessed it with 12 guesses
Your program will be keeping track of two key pieces of information. First, the dashed version of the movie that is partially filled in. For this program, we're going to represent this as a list of strings. For example, in the transcript shown above, the list would start out as:
['-', '-', '-', '-', '-', '-', '-', '-', ' ', '-', '-', '-', '-', '-', ' ', '-', '-', '-', '-']
With each position corresponding to a letter (including spaces) in the movie TOMORROW NEVER DIES. As the user guesses correctly, this will be updated. For example, after guessing 'E' and 'A' this list would then be:
['-', '-', '-', '-', '-', '-', '-', '-', ' ', '-', 'e', '-', 'e', '-', ' ', '-', '-', 'e', '-']
Which we see displayed as:
Movie: - - - - - - - - - E - E - - - E -
The second piece of information that you'll need to keep track of is the list of letters that have been guessed so far. Again, we'll just use a list of strings to keep track of this. The program then revolves around:
Make sure you understand the basic setup of how we're going to tackle this problem!
Besides following the game specification described above, your program must meet the following requirements:
generate_underscore
, which takes the movie (as a string) as a parameter and returns a list representing the underscored version of the word where each character in the movie is represented as a dash (`-'), except for spaces, which are kept as spaces.
>>> generate_underscore("monsters inc") ['-', '-', '-', '-', '-', '-', '-', '-', ' ', '-', '-', '-']
list_to_string
, which takes a list of strings as a parameter and returns the letters in the list as a single string, with each letter capitalized and separated by a space.
>>> monster = generate_underscore("monsters inc") >>> list_to_string(monster) '- - - - - - - - - - -'
insert_letter
, which takes three parameters: a letter (as a string), a list of strings representing the current dashed version that the user has filled in so far and, the movie that the user is trying to guess (as a string). This function should update the current dashed version of the movie assuming the user guessed the letter AND assuming that the letter is in the movie. This function can either modify the existing dashed list (and then not return anything) or it can return a new list. Make sure you understand the difference between these two approaches and actively decide on one or the other (personally, I find the latter easier to test and reason about). Here would be the output of the function if it returned a new list:
>>> insert_letter("k", ['-', '-', 'n', 'g', ' ', '-', '-', 'n', 'g'], "king kong") ['k', '-', 'n', 'g', ' ', 'k', '-', 'n', 'g']
Hint: Notice that there is a direct, index-wise correspondence between the dashed version of the word and the word itself, e.g. for the example above (adding some spaces to make it line up):
['-', '-', 'n', 'g', ' ', '-', '-', 'n', 'g'] 0 1 2 3 4 5 6 7 8 ' k i n g k o n g'
Use this correspondence to make your implementation easier!
play_hangman
, which takes no parameters. This function should initiate the hangman game and continue to run until the game finishes.There are many different ways to implement your program, but here is one suggestion:
generate_underscore
function. The only tricky thing here is that you need to do something different depending on whether the letter is a space or not. Remember, we can iterate over the characters in a string using a for
loop.list_to_string
function. This should be very similar to list functions you've written previously (or that we've looked at in class). There is a string method called upper
that might be useful.insert_letter
function. There are many ways to do this, so think about how you'd like to approach it. The key observation here is that the movie to be guessed and the list representing the current dashed version of the movie are of the same length and there is a direct correspondence between the two, as noted above.play_hangman
incrementally, testing each step before moving on to the next:
choice
in the random
module that might be useful, though there are many ways to do this. Also, there is a method of the string class called title
that will help your output look nicer. Note, when you're developing, feel free to print out other information (like the word you're supposed to be guessing) to help you debug your program. Just make sure to remove this information before you hand it in.Here are some things to think about:
Make sure your program is well-commented, follows naming conventions, uses good variable names, uses whitespace properly, and doesn't have overly long lines. Ensure that all your loops and conditionals are actually necessary.
Feature | Value |
---|---|
A different random movie is picked each time | 1 |
Movie information is displayed appropriately | 1 |
Initial underscored word shows correctly | 2 |
Each guess is inserted properly in underscored movie | 3 |
Guessed letters are correctly displayed | 2 |
Letters in the movie title are updated correctly | 1 |
Game ends when movie is guessed | 2 |
Game win output printed correctly | 1 |
Handles lower- and upper-cased letters | 1 |
Follows function specifications (autograder) | 11 |
Comments, style | 5 |
Total | 28 |