6.00: Introduction to Computer Science and Programming
Problem Set 3: Word Game
Handed out: Tuesday, September 29, 2009
Interim due date: 11:59pm Friday, Oct. 2, 2009. You can
optionally submit solutions to Problems #1-3 to earn an extra
late day that you can use for this or future problem sets.
Final due date:
11:59pm Tuesday, Oct 6,
2009. All problems due.
NOTE: This problem set is challenging. We strongly recommend
that you start working on it early, and try to complete Problems #1-3
by the interim deadline.
As children, we loved word games like Hangman. So, like any good parent or teacher, we'll now force you to do the things that interested us when we were younger. In this problem set, you'll implement two word games: first, we'll help you through implementing the 6.00 word game, and then you'll implement Hangman on your own.
Don't be intimidated by the length of this problem set. It's a lot of reading, but should all be doable.
Let's begin by describing the 6.00 word game: This game is a lot like Boggle or Text Twist, if you've played those. Letters are dealt to players, who then construct one or more words out of their letters. Each valid word receives a score, based on the length of the word and the letters in that word.
The rules of the game are as follows:
Workload
Please let us know how long you spend on each problem. We want to be
careful not to overload you by giving out problems that take longer
than we anticipated.
Collaboration
Please take note
of the policy in
the
course information handout.
If everything is okay, after a small delay, you should see the following printed out:
Loading word list from file... 55900 words loaded. play_game not implemented. play_hand not implemented.If you see an IOError instead (e.g., No such file or directory), you should change the value of the WORDLIST_FILENAME constant (defined near the top of the file) to the complete pathname for the file words.txt (This will vary based on where you saved the file).
# ----------------------------------- # Helper code # (you don't need to understand this helper code). . .
# (end of helper code) # -----------------------------------
We have provided several test functions to get you started. As you make progress on the problem set, run test_ps3.py as you go.
If your code passes the unit tests you will see a SUCCESS message; otherwise you will see a FAILURE message. These tests aren't exhaustive. You may want to test your code in other ways too.
If you run test_ps3.py after downloading it, you should see that all the tests fail. These are the provided test functions:
The first step is to implement some code that allows us to calculate the score for a single word.
Fill in the code for get_word_score in ps3.py:
You may assume that the input is always either a string of lowercase letters, or the empty string "". You may want to use the VOWELS and CONSONANTS constants defined at the top of ps3.py. You should not change their values.
Testing:
If this function is implemented properly, and
you run test_ps3.py, you should see that the
test_get_word_score() tests pass.
Also test your implementation of get_word_score, using some
reasonable English words.
a, q, l, m, u, i, l
A straightforward way to represent a hand in Python is as a list:
hand = ['a', 'q', 'l', 'm', 'u', 'i', 'l']
However, we'll represent the hand in a different way, because it simplifies the code we'll need in the update_hand and is_valid_word functions. (In general, there are many ways to represent, in code, various concepts -- some are better suited to certain operations than others).
In our program, a hand will be represented as a dictionary: the keys are (lowercase) letters and the values are the number of times the particular letter is repeated in that hand. For example, the above hand would be represented as:
hand = {'a':1, 'q':1, 'l':2, 'm':1, 'u':1, 'i':1}
Notice how the repeated letter 'l' is represented.
The player starts with a hand, a set of letters. As the player spells out words, letters from this set are used up. For example, the player could start out with the following hand:
a, q, l, m, u, i, l
The player could choose to spell the word quail. This would leave the following letters in the player's hand:
l, m
You will now write a function that takes a hand and a word as inputs, uses letters from that hand to spell the word, and returns the remaining letters in the hand.
For example:
>> hand = {'a':1, 'q':1, 'l':2, 'm':1, 'u':1, 'i':1}
>> display_hand(hand)
a q l l m u i
>> hand = update_hand(hand, 'quail')
>> hand
{'l': 1, 'm': 1}
>> display_hand(hand)
l m
(NOTE: alternatively, in the above example, after the call to update_hand the value of hand could be the dictionary {'a':0, 'q':0, 'l':1, 'm':1, 'u':0, 'i':0}. The exact value depends on your implementation; but the output of display_hand() should be the same in either case.)
Testing:
Make sure the test_update_hand() tests
pass. You may also want to test your implementation of
update_hand with some reasonable inputs.
At this point, we have written code to generate a random hand and display that hand to the user. We can also ask the user for a word (Python's raw_input) and score the word (using your get_word_score). However, at this point we have not written any code to verify that a word given by a player obeys the rules of the game.
A valid word is: in the word list; and it is composed entirely of letters from the current hand.
Testing:
Make sure the test_is_valid_word tests
pass. In particular, you may want to test your implementation by
calling it multiple times on the same hand - what should the correct
behavior be?
HINT: You may find the get_frequency_dict function useful (defined near the top of ps3.py). When given a string of letters as an input, it returns a dictionary where the keys are the letters and the values are the number of times that letter is repeated in the input string. For example:
>> get_frequency_dict("hello")
{'h': 1, 'e': 1, 'l': 2, 'o': 1}
As you can see, this is the same kind of dictionary we have been using to represent hands.
We are now ready to begin writing the code that interacts with the player.
Testing:
Try out your implementation as if you were playing the game.
Here is some example output of play_hand (your output may differ, depending on what messages you print out):
Current Hand: a c i h m m z Enter word, or a . to indicate that you are finished: him him earned 15 points. Total: 15 points Current Hand: a c m z Enter word, or a . to indicate that you are finished: cam cam earned 15 points. Total: 30 points Current Hand: z Enter word, or a . to indicate that you are finished: . Total score: 30 points.
A game consists of playing multiple hands. We need to implement one final function to complete our word-game program.
There is no coding for this question - the only "work" you have to do here is actually just uncommenting some lines and deleting some other lines of code.
For the game, you should use the HAND_SIZE constant to determine the number of cards in a hand. If you like, you can try out different values for HAND_SIZE with your program.
Testing:
Try out this implementation as if you were playing the game.
For this problem, you will implement a variation of the classic wordgame, Hangman. For those of you who are unfamiliar with the rules, you may read all about it here. In this problem, the second player will always be the computer, who will be picking a word at random.
Download and save ps3_hangman.py into the same directory as your work for this problem set. This file will provide you with the function to load the word list.
Make sure your file runs properly before editing. You should get the following output when running the unmodified version of ps3_hangman.py.
Loading word list from file... 55900 words loaded.
You will want to do all of your coding for this problem within this file as well because you will be writing a program that depends on each function you write.
Here are the requirements for your game:
Welcome to the game, Hangman! I am thinking of a word that is 4 letters long. ------------- You have 8 guesses left. Available letters: abcdefghijklmnopqrstuvwxyz Please guess a letter: a Good guess: _a__ ------------ You have 8 guesses left. Available letters: bcdefghijklmnopqrstuvwxyz Please guess a letter: s Oops! That letter is not in my word: _a__ ------------ You have 7 guesses left. Available letters: bcdefghijklmnopqrtuvwxyz Please guess a letter: t Good guess: ta_t ------------ You have 7 guesses left. Available letters: bcdefghijklmnopqruvwxyz Please guess a letter: r Oops! That letter is not in my word: ta_t ------------ You have 6 guesses left. Available letters: bcdefghijklmnopquvwxyz Please guess a letter: m Oops! That letter is not in my word: ta_t ------------ You have 5 guesses left. Available letters: bdefghijklnopquvwxyz Please guess a letter: c Good guess: tact ------------ Congratulations, you won!
Do not be intimidated by this problem! It's actually easier than it looks. Make sure you break down the problem into logical subtasks. What functions will you need to have in order for this game to work?
This completes the problem set!
2. Time and collaboration info
At the start of the file, in a comment, write down the number of hours (roughly) you spent on this problem set, and the names of whomever you collaborated with. For example:
# Problem Set 3 # Name: Jane Lee # Collaborators (Discussion): John Doe # Collaborators (Idential Solution): Jane Smith # Time: 1:30 # .... your code goes here ...
3. Submit
Upload the
file to your
workspace. If there is some error uploading to your workspace,
email the file to 6.00-staff [at] mit.edu.
You may upload (or email) new versions of the problem set until the 11:59pm deadline, but anything uploaded after that will be ignored.