CMU 15-112: Fundamentals of Programming and Computer Science
Homework 4 (Due Sunday 28-Feb at 11am)
- This homework is solo. You must not collaborate with anyone (besides current course TA's and faculty) in any way. See the syllabus for more details.
- To start:
- Create a folder named 'week4'
- Download these files into that folder:
- Edit hw4.py using VSCode
- When you have completed and fully tested hw4, submit hw4.py to Autolab. For this hw, you may submit up to 5 times, but only your last submission counts.
- There is no autograder for hw4. The TA's will manually grade your last submission sometime soon after the hw deadline.
- Do not use lists, list indexing, or recursion.
Please note:
- This hw will not have spicy problems. Instead, you may enjoy the bonus problem.
- Remember, we will grade this hw for style!
- Study the Notes!!! [0 pts]
Important: due to the campus-wide Break Day on Tuesday, this week has a very unusual schedule (unprecedented, actually). Your first formal exposure to the material is on Thursday. You may consider waiting until after then to start this hw. But if you start sooner, be certain to first carefully study the notes, including watching the videos in the notes. Starting the hw without first understanding this new material will result in a very long, frustrating experience. So avoid that time-wasting stress and frustration and be sure to study the notes before starting this hw! - The Word Guessing Game! [100 pts]
Starting from hw4.py, write the "Word Guessing Game" as shown in this video:
Here are some very important hints:- First study the course notes (carefully!)
One last time: do not start this hw until you really understand this week's material! Study the course notes carefully! - Watch the hw4 writeup video (carefully!)
Next, watch the hw4 writeup video (see link above). Seriously. Watch it carefully. Do not skip this step! You may want to watch it more than once (truly). - Read all the hints (carefully!)
Next, read all these hints, carefully. All of them! Do not start before you do that, or you may miss a really helpful hint that could save you tons of time! - Work on one feature at a time
Writing a complete working app, even a smaller one, can be a daunting experience, especially the first few times you do it. To make this more manageable, break the problem down into smaller parts. Solve this one feature at a time. For example, maybe first just draw the title. Then, choose a random word and draw the underlines in place of the letters of the word. Then, actually draw the word instead of the underscores when the user presses the mouse (and hide it again if they press the mouse again). And so on. - Match the video closely (but not necessarily identically)
Your graphics need to closely match those in the video. They don't have to be identical. So we may have used a 30-point font where you use a 28-point font, and that's fine. But they have to be close. If you look closely, you'll see that we used several different font sizes, and the letters are not only smaller but not bold. You will have to match those design decisions closely. - How to randomly choose the next word
Be sure that you save common-words.txt in the same folder as your hw4.py file. Then, load the file contents using thereadFile()
function from the Strings notes (and also provided for you in the hw4.py starter file). Then uses.splitlines()
to convert that multi-line string into a list. And then userandom.choice()
to choose a random word from that list. That is, do something like this:fileContents = readFile('common-words.txt') word = random.choice(fileContents.splitlines())
That said, you could be a bit more efficient and store the fileContents in the app object so you only load the file once, rather than once for each time you choose a random word. - How to get the elapsed time
Usetime.time()
to get the current time, sort of. This function gives you the number of seconds since some date a long time ago. That's not so helpful by itself. But if you calltime.time()
twice, and take the difference between the results, that will be the elapsed time, in seconds, between those calls. So: calltime.time()
at the start of a round, store that value, and then in timerFired you can calltime.time()
again, and compute the difference to get the elapsed time for that round. - How to tell if the user entered a letter
In your keyPressed function, event.key holds the key that was just pressed. You can use s.isalpha() to test if it is a letter (an "alphabetic"). However, some keys have longer names like 'Up', 'Down', 'Tab', or 'Enter'. So you should also make sure that event.key has a length of just one character. Also, be sure to add one to the guess count each time a letter is pressed, even if it that letter was already guessed. - Remember to show/hide the word on mouse presses
Don't forget to include the debugging and grading super power where pressing the mouse when the word is not yet fully guessed results in the word being exposed until the next key press or mouse press. Hint: for this, we used app.showWord, a boolean that we initialized to False, but toggled (changed from True to False or False to True) on each mouse press. - Use 'pink' and 'lightGreen' as your colors
We used 'pink' and 'lightGreen' as the colors for the dots around the letters that have been guessed. Pink is for a letter not in the word, and lightGreen for a letter that is in the word. - Draw the green rectangle!
Remember to draw a green rectangle under the word when it is fully guessed (so draw the green rectangle first and then draw the word over it). Give the user some positive reinforcement! Really, users respond well to this. - Remember to ignore key presses when the word is guessed
After the word is fully guessed (so, while the green rectangle is drawn), you should ignore all key presses. This continues until there is a mouse press, which restarts the game with a new word. - How to restart the app
You should have write a helper function that you call to restart the app. It should set the guess count back to 0, choose a random word, set the initial time using time.time(), and whatever else you need to set up a new round. Hint: to avoid duplicating code, you should call this helper function from your appStarted() function to set up the very first round. - Be case-insensitive
Be sure to allow for case-insensitive input, so both 'a' and 'A' are treated as 'A'. You may want to use s.upper() for this. - Use these message strings
Here are the message strings we used at various times in our sample solution. Here, we use the letter 'A', or the '#' symbol, but you need to change that to use whichever letter is appropriate at that time (hint: maybe use f strings for that).- Guess a letter...
Displayed at the start of a round. - '#' is not a letter!
Displayed when they enter a key that is not a letter. - You already guessed 'A'. Guess again.
Displayed when they guess a letter that they already guessed. - Good job! Keep guessing...
Displayed when they guess a letter that is in the word. - Sorry... Guess again.
Displayed when they guess a letter that is not in the word. - You got it! (press the mouse to restart)
Displayed when they guessed the entire word.
app.message
. - Guess a letter...
- Use these drawing helper functions
We found it very helpful to use several drawing helper functions. So this is what our redrawAll looks like:def redrawAll(app, canvas): drawTitle(app, canvas) drawDisplayWord(app, canvas) drawGuesses(app, canvas) drawGuessCount(app, canvas) drawElapsedTime(app, canvas) drawMessage(app, canvas)
- Use your resources wisely
Be sure to go to OH (both TA and faculty) and ask good questions on piazza. These can be enormous time-savers for you! There are 50 TA's and 2 faculty here to help you. Let us help you!!! - Have fun!
For many of you, this will be the first real app you have ever made. Sweet! Enjoy the experience! Truly!
- First study the course notes (carefully!)
- Hw4 Bonus Mode [up to 4 pts]
For a small amount of bonus points, but mostly for the fun of it, you may add some fun bonus features to your game. Just follow these guidelines so that we can find your features and give you proper credit for them:- If the user presses '!', print (in the console) a description of all of your bonus features. Be brief, but tell us what features you added and -- crucially -- how we can see them in action.
- Also, by pressing '!', your app switches from "standard" mode to "bonus" mode. This is important because you may want to change some of the behaviors listed above, but you have to match those behaviors to get full credit on the hw. So, the app starts in "standard" mode, and runs exactly as described above. Then, when the user presses '!', the app goes into "bonus" mode, where you can change the behavior as you see fit.
For example, in your bonus mode you may wish to add some graphics to make the game more like a traditional "Hangman" game. Or you may want to somehow transform the app into a competitive 2-player game. Or... You get the idea. Be creative, do great things, and have fun!!!!