Please read through the *entire* lab before starting! Also, as always, run update21 to create your cs21/labs/07 directory and create your programs for lab 7 in this directory.
Over the next two weeks, you will write a program that plays a word game called lingo.
For this lab, you will focus on using top-down design to create the overall structure of the program. Once your proposed design has been reviewed by your professor, you will use bottom-up implementation and unit testing to incrementally construct the full program.
Run update21, if you haven't already, to create the cs21/labs/07 directory. 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):
$ update21 $ cd cs21/labs/07 $ vim lingo.py
For this assignment, you will write a program that implements the TV game show Lingo. The focus of this assignment is for you to practice using top-down design to construct your solution incrementally.
Lingo is a turn-based guessing game. The computer selects a random word and the player tries to guess the word. Each guess must also be a valid word of the same length (this is what makes the game interesting and hard). After a guess is made, the computer provides status information about how close (or how far) the player is to arriving at the solution. The status information includes which letters are correct, but in the wrong position, and which letters are correct, and in the right position.
To make things concrete, let's use an example where the computer is selecting a five-letter word. Normally, as a player of the game, you would not know what the computer had chosen. However, let's make things easier and peek at the computer's choice: guava.
It's time for you to begin guessing the word. Your initial guess is:
spray. Notice that there is only one letter that you guessed
that's also in the target word (the letter a). Rather than
indicate the number of letters you have correct, the status message
will specify which letters are exactly correct and which are in the
sequence, but in the wrong place. You'll do this by
UPPER-CASING the
exact matches, leaving the 'inexact' matches alone, and replacing the
wrong letters with dashes. So, in this case, where the letter
a of your guess spray is an 'inexact' match, you'd
receive the status message:
---a-
Clearly you don't know the word yet, so you make another guess:
arrow. Again, the only correct letter is the a, and
now it's in a different wrong place. So, the status you would receive
is:
a----
Your next guess is again. This time the guessed word has two a's, as does the secret word. The first guessed a is in the wrong position and will appear as lower case, but the second guessed a is in the correct position (the third character) and should show up as an UPPERCASE letter in the status. There is also a correctly guessed g but it is in the wrong position and will appear as lower case. Since neither the i nor the n appear in the target word, the status of this guess is the following: agA--
Your next guess is games. While it's true that you know there
are no s's in the solution (from your guess of spray
earlier), you're trying to see if some of these other letters are
present (the m and e) and you're still
trying to figure out where the other a goes. The status message
now that you have the g in the right position and the a
is still in the wrong position:
Ga---
Here is this example as it may appear in a game (see the Sample Output section below for other examples of a working solution):
Enter a 5 letter word: spray - - - a - Enter a 5 letter word: arrow a - - - - Enter a 5 letter word: again a g A - - Enter a 5 letter word: games G a - - - Enter a 5 letter word: curve - U - V - Enter a 5 letter word: suave - U A V - Enter a 5 letter word: guava You won in 7 turns!
You should use Top-Down Design and your program's structure should reflect this.
For this lab you must turn in your top-down design first! You should create your design in a file called design.py and email it to your professor. We will then look over your design, make comments on it, and send it back. If we think your design is inadequate, we will ask you to fix and resubmit it. Once we have approved your top-down design, you can implement the full program.Here are the top-down design requirements:
$ cd cs21/labs/07 $ mail adanner < design.py
Here is an example of a stubbed out program. What you email us should be similarly structured.
NOTE: once you email us your design, we will try to get comments back to you within 24-36 hours. However, if everyone emails us their design at the same time, it may take longer. You are encouraged to start your design early, so you have enough time to get our helpful comments and still implement the full program.
No designs will be accepted after Thursday, Nov 1.
Once your design has been approved, copy it to another file to implement your game:
$ cd cs21/labs/07 $ cp design.py lingo.py $ vim lingo.py
if word in wordList: ...
>>> word = "apple" >>> word 'apple' >>> charList = list(word) >>> charList ['a', 'p', 'p', 'l', 'e'] >>> rejoined = ''.join(charList) >>> rejoined 'apple'
You may want to first get the entire flow of control in the program correct, with incorrect status updates (perhaps ignoring double characters in guessed and target word, and ignoring the correct position part) , and then go back and work on getting the status update part correct.
We suggest that you store the secret word and the guessed word as strings. Then, to produce the status information, create list versions of these words that can be modified. You can use the list version of the guessed word to hold the status information.
Our suggested algorithm is to handle the exact matches first, then worry about the inexact matches.
First search for exact matches. When an exact match is found, change the letter in the guessed word to upper case and hide the letter in the secret word by changing it to some other character, such as '.' (you don't want to find it again when you search for inexact matches).
For example, given the target word guava and the user guess gulag, we expect the status message: GU-a-. We'll start by converting both the target and the guess into lists:
target: ['g','u','a','v','a'] guess: ['g','u','l','a','g']
Now, we'll check for exact matches, beginning from left to right in the guess list. "Does the first letter of 'gulag' match the first letter of 'guava'?" It does, so we'll capitalize the first letter of the guess list and we'll change the first letter of the target list to a period:
target: ['.','u','a','v','a'] guess: ['G','u','l','a','g']
Next, "Does the second letter of 'gulag' match the second letter of 'guava'?" It does again, so we'll capitalize the second letter of the guess list and we'll change the second letter of the target list to a period:
target: ['.','.','a','v','a'] guess: ['G','U','l','a','g']
Next, we'll ask if the third, fourth, or fifth letters match, and none will, so the two lists will remain unchanged.
We move on to finding inexact matches. For each letter in the guess list, we do the following:
Following this algorithm, we look at the first letter is the guess list: G. Since it's capitalized, we go on to the next letter: U. It, too, is capitalized, so we move on to the third letter, l, which is not in the target list, so we replace the letter in the guess list with a '-':
target: ['.','.','a','v','a'] guess: ['G','U','-','a','g']
The fourth letter in the guess list, a, is in the target list, so we replace the letter in the target list with a '.':
target: ['.','.','.','v','a'] guess: ['G','U','-','a','g']
The final letter in the guess list, g, is not in the target list, so replace the letter in the guess list with a '-':
target: ['.','.','.','v','a'] guess: ['G','U','-','a','-']
The guess list is now nearly the status information which you need to provide. You just need to join the letters in the list together to form the string 'GU-a-'.
Here is some sample output from three runs of a lingo program, notice the error handling:
$ python lingo.py @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Welcome to Lingo Each turn you will try to guess the secret word If you guess the word, you win If you guess some letters in the word, lingo will display: guessed letters in the correct position in upper case guessed letters in the incorrect position in lower case Good Luck! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ word: - - - - - Guess a 5 letter word: hello word: - e l - - Guess a 5 letter word: letter Invalid Input, enter a word with 5 characters. try again... Guess a 5 letter word: oops Invalid Input, enter a word with 5 characters. try again... Guess a 5 letter word: helpm Invalid Input, helpm is not a valid word. try again... Guess a 5 letter word: piles word: P I l E - Guess a 5 letter word: pixel You guessed the word in 3 tries. Congratulations! $ python lingo.py @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Welcome to Lingo Each turn you will try to guess the secret word If you guess the word, you win If you guess some letters in the word, lingo will display: guessed letters in the correct position in upper case guessed letters in the incorrect position in lower case Good Luck! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ word: - - - - - Guess a 5 letter word: snort word: - - - r - Guess a 5 letter word: retort Invalid Input, enter a word with 5 characters. try again... Guess a 5 letter word: great word: - r - a - Guess a 5 letter word: barks word: b A r - - Guess a 5 letter word: rstuv Invalid Input, rstuv is not a valid word. try again... Guess a 5 letter word: roles word: R - - - - Guess a 5 letter word: ramps word: R A - - - Guess a 5 letter word: rabid word: R A B i - Guess a 5 letter word: rabbi You guessed the word rabbi in 7 tries. Congratulations! $ python lingo.py @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Welcome to Lingo Each turn you will try to guess the secret word If you guess the word, you win If you guess some letters in the word, lingo will display: guessed letters in the correct position in upper case guessed letters in the incorrect position in lower case Good Luck! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ word: - - - - - Guess a 5 letter word: grill word: - - i l - Guess a 5 letter word: trips word: t - i p - Guess a 5 letter word: QUIT The word you were trying to guess is: plait Better luck next time!
Warning: When you get this working, be prepared to spend a while playing as it is remarkably addictive!
Once you are satisfied with your program, hand it in by typing handin21 in a terminal window.