CS21 Lab 7: Word scramble

Design is due Saturday, March 18, before midnight (done with a partner) — Get this done early!

Full Implementation is due Saturday, March 25, before midnight (done individually)

Goals

  • practice using top-down design

  • write a complex program, with multiple functions, from scratch

  • use the random library

  • validate user input

  • unit testing

  • reading from files

Notes

Please read through the entire lab before starting!

This is a two-part lab, split over two weeks. For the first week you will work with a partner and focus on using top-down design to create the overall structure for the program. Once your partnerships' proposed structure has been reviewed and approved by your professor (either your class professor or your lab professor), you will each individually use bottom-up implementation to complete the full program.

You have two weeks to complete the full program. The first week is for the design, and the second for the full program. Your initial top-down design is due this Saturday (March 18) and the full implementation the following week (March 24). We highly recommended that you submit your top-down design as soon as possible so that we have time to give you feedback before you begin your full implementation. If you submit your design on the last day at midnight, it might take us a few days to get to it and send you comments.

The list of partnerships is available on EdStem.

Please see the following guidelines for lab partnerships for information about how to best collaborate with a partner on lab assignments.

1. Word scramble

We will write a two-player game called "word scramble." This is a word search game where players attempt to make words using letters from a provided selection.

The goal is to find as many words as possible, subject to the rules of the game, which are listed below under "requirements".

Players attempt to find as many possible valid words as they can.

At the end, the player with the most valid words is the winner.

1.1. Demonstration game

Let’s take a look at a demonstration game to get a better sense of how the game works.

Welcome to word scramble!

Try to make as many words as you can with the given letters!
Words must be at least 3 letters long.

Is player 1 ready (yes or no)? yes

Your letters are:
A E L X P P

Enter your words (enter 'q' when you are ready to quit):
axe
ax
peel
lale
leap
lip
all
apple
q

Sorry, you had some invalid words:
  "ax" is too short
  "lale" is not a valid word
  "lip" uses letters which are not available

At this point it is now player 2’s turn, so the welcome message gets printed again.

Welcome to word scramble!

Try to make as many words as you can with the given letters!
Words must be at least 3 letters long.

Is player 2 ready (yes or no)? yes

Your letters are:
A E L X P P

Enter your words (enter 'q' when you are ready to quit):
peep
ale
pedal
expel
elee
q

Sorry, you had some invalid words:
  "pedal" uses letters which are not available
  "elee" is not a valid word

FINAL OUTCOME:

Player 1 found 5 words.
Player 2 found 3 words.

Player 1 wins!

1.2. Game Requirements

You have a lot of freedom to design the game how you want to look, but here are our requirements:

  • The game should generate a set of 6 letters at random. At least 2 of them must be vowels.

  • All words must be at least 3 letters long.

  • All words must be found in the dictionary provided. (You do not need to copy the entire dictionary file into the directory where you are working on your lab! You can simply open the file /usr/local/doc/word-scramble-dictionary.txt. This file contains the 10000 most frequently used English words AND all 3- and 4-letter Scrabble words.)

  • The words can only use the letters provided. Any words that use unavailable letters are invalid.

  • You may assume that each player will never reuse the same word twice.

  • Upper- and lower-case words should be considered the same. So in the example above, "apple" and "Apple" and "aPpLE" would all be valid words using the given letters.

  • Your game must include at least one function which modifies a list.

For example, you will need to store each player’s entered words in a list as they are entered. Later in the program, when you eliminate the invalid words, you must change the contents of that list. You might choose to design a function called eliminate_too_short_words(player_words) which takes one parameter, the list of the player’s words, and eliminates the words which are shorter than 3 letters.

Before calling this function, the list for player 1 in the example above is:

player1words = ["axe", "ax", "peel", "lale", "leap", "lip", "all", "apple"]

After calling this function, the list should change:

eliminate_too_short_words(player1words)
print(player1words)

This will print as output:

["axe", "---", "peel", "lale", "leap", "lip", "all", "apple"]

Notice that the word "ax", which was too short, has been replaced in the list with a special string "---" which indicates that it is "crossed out".

1.3. Example program runs

Here are several more examples of the game running so you can see examples of how the game works.

2. Top-Down Design requirements

You and your partner should complete your top-down design (TDD), submit it, and obtain feedback on it before you individually begin the full implementation.

2.1. Special procedures for this lab:

  • create design-word-scramble.py first.

  • after you have a working design (see below), you and your partner should both run handin21 to turn it in! After running handin21, send an email to tdd@cs.swarthmore.edu (with your TDD file as an attachment), letting us know your design is done. We will take a look at each design and send you comments (usually within a day or two). If the design is incomplete or insufficient, you may be asked to submit a second design.

  • After you have the design and have heard back from us, copy the file to word-scramble.py (ex. cp design-word-scramble.py word-scramble.py, or use "Save As" in Visual Studio Code) and implement the full program. Leave design-word-scramble.py as it is. Work by yourself for the implementation portion of this lab.

2.2. Requirements for TDD

Please ensure your design meets the following requirements before submitting:

  • main() should be completely written, and should perform high-level steps without focusing on details.

  • main() should call the functions you create in your design, in the appropriate order, and with arguments that match parameters. Return values should be saved in main(), even if you don’t do anything with them yet.

  • Your design should contain several functions. Each function should be function worthy (i.e., not a trivial task). Each function should also demonstrate encapsulation (one clearly defined purpose)

  • Every function you have designed should be called somewhere in your program. Most of the functions will probably be called from main(). If you have helper functions that get called from inside other functions, make sure you have included those calls in your design document.

  • All functions should be stubbed out with parameters, a block comment, and a return statement. They don’t need to do anything yet, except possibly call other functions.

  • If your function is supposed to return something, you should return a dummy value of the appropriate type (e.g. return 0 for an int, [1,2,3] for a list, …​).

  • Your design should make it clear how you are handling wrong words and where you are printing out the error messages. (If these are side effects, you need to include that note in your function stub comment!)

  • The design should run without syntax errors (even if it doesn’t do much).

3. Implementation

Once you have received feedback about your top-down design from your professor you can start individually working on the implementation of your program in word-scramble.py.

Begin with a copy of your TDD solution as a starting point for your full implementation. To do this, copy the file to word-scramble.py (ex. cp design-word-scramble.py word-scramble.py, or use "Save As" in Visual Studio Code) and implement the full program. Leave design-word-scramble.py as it is. Work by yourself for the implementation portion of this lab.

3.1. Implementation requirements

In addition to supporting the requirements of the program listed above, your implementation should:

  • main should just reflect the high-level steps of your program. Details of steps should be encapsulated in functions called by main. The key is that main is very simple, easy to read, and reflects the big steps of the program.

  • use meaningful names for variables, functions, and parameters

  • be robust to bad input

  • be well-commented

Hint: use helper functions! For example, if checking for invalid words seems like a big problem, you can make it have its own function (which gets called from another function in that is organizing all of the different checks for invalid words).

3.2. Word file

This is the word file your program should use: /usr/local/doc/word-scramble-dictionary.txt. Its format is a single word per line. For example, here is a very small file of 4 words of this format:

pelican
computer
absail
mysterious

You can open the file to see its contents: vcode /usr/local/doc/word-scramble-dictionary.txt.

  • Look at the examples of file I/O code we saw in class for how to read in one or more words from this file.

  • Look at the previous class examples to see how we used the random library to make a random choice between many possible things (you will have to pick letters at random).

3.3. Checking for invalid letters

Checking that the user has entered words only using the available letters can be tricky. Your list of user words will already probably include some words that have been crossed off as "---". These words can be ignored when you are checking for invalid letters, since they are already crossed off! You might need to do an extra check in your loop in order to make sure you ignore "---".

Here’s one plan for how to check for invalid letters: first, look through your list of words. For each word, if that word is already "---", you can skip the rest of the checks (because you already know that word is invalid). If the word is not crossed off already, then look through each letter in each word and check if that letter is not among the letters available. If the letter is not available, then this word should be handled as one of the disallowed words.

There are several ways you can "skip" the already-crossed-off "---" words. One way to handle this, if you choose to use a for loop to look through the words, is using break. The break command will end the loop without continuing to the end of the assigned range. Alternately, you can use Boolean flags.

3.4. Tips

  • Use incremental implementation and test as you go. Implement all or part of a function, add a test to call it. Test it for correctness. Then add a little bit more.

  • You will need to keep track of the list of letters, the words player 1 entered, the words player 2 entered, the list of all possible words in the dictionary, and maybe more lists. Use separate lists for these, and give them meaningful variable names to avoid confusion!

4. Optional challenges

Here are a few optional challenges for this game. If you do these (just for fun, no extra points!), please copy your working game to a new file: cp word-scramble.py word-scramble-extra.py.

  • Add a check so that players cannot enter the same word multiple times (so entering "ale", "ale", and "ale" would be only one valid word for the example above).

  • Add an option where players can choose how many letters they get given at the beginning of the game.

  • Change the scoring so that players only receive credit for unique words they find --- for example, if both players find the word "giraffe" then that word does not count (gets crossed off).

  • Add an option where players score more points for longer words (length 3 or 4 earn 1 point each, length 5 earns 2 points, length 6 earns 3 points, length 7 and longer earns 5 points each).

  • Add an option which penalizes a player -1 point for each invalid word they enter.

  • After reporting the winner, ask the players if they want to play another round. (Alternately, have them play 3 rounds and make the scores cumulative.)

  • Before the game shows the user the letters, use the dictionary to figure out all possible words and report this to the user. (For example, by displaying a message: There are 35 possible 3-letter words, 17 possible 4-letter words, 10 possible 5-letter words, and 1 possible 6-letter word.) After the game ends, report which words the players missed, to help them improve for next time!

5. Answer the Questionnaire

Each lab will have a short questionnaire at the end. Please edit the Questions-07.txt file in your cs21/labs/07 directory and answer the questions in that file.

Once you’re done with that, you should run handin21 again.

Submitting lab assignments

Remember to run handin21 to turn in your lab files! You may run handin21 as many times as you want. Each time it will turn in any new work. We recommend running handin21 after you complete each program or after you complete significant work on any one program.

Logging out

When you’re done working in the lab, you should log out of the computer you’re using.

First quit any applications you are running, like the browser and the terminal. Then click on the logout icon (logout icon or other logout icon) and choose "log out".

If you plan to leave the lab for just a few minutes, you do not need to log out. It is, however, a good idea to lock your machine while you are gone. You can lock your screen by clicking on the lock xlock icon. PLEASE do not leave a session locked for a long period of time. Power may go out, someone might reboot the machine, etc. You don’t want to lose any work!

Resources

Programming Tips

As you write programs, use good programming practices:

  • Use a comment at the top of the file to describe the purpose of the program (see example).

  • All programs should have a main() function (see example).

  • Use variable names that describe the contents of the variables.

  • Write your programs incrementally and test them as you go. This is really crucial to success: don’t write lots of code and then test it all at once! Write a little code, make sure it works, then add some more and test it again.

  • Don’t assume that if your program passes the sample tests we provide that it is completely correct. Come up with your own test cases and verify that the program is producing the right output on them.

  • Avoid writing any lines of code that exceed 80 columns.

    • Always work in a terminal window that is 80 characters wide (resize it to be this wide)

    • In vscode, at the bottom right in the window, there is an indication of both the line and the column of the cursor.

Function Comments

All functions should have a top-level comment! Please see our function example page if you are confused about writing function comments.

Are your files in the correct place?

Make sure all programs are saved to your cs21/labs/07 directory! Files outside that directory will not be graded.

$ update21
$ cd ~/cs21/labs/07
$ pwd
/home/username/cs21/labs/07
$ ls
Questions-07.txt
(should see your program files here)