Instructions for wordGuesser

(produced at 17:39 UTC on 2024-09-30)

This task is part of project05 which is due at 23:00 EDT on 2024-10-08.

You have the option to work with a partner on this task if you wish. Working with a partner requires more work to coordinate schedules, but if you work together and make sure that you are both understanding the code you write, you will make progress faster and learn more.

You can download the starter code for this task using this link.

You can submit this task using this link.

Put all of your work for this task into the file wordGuesser.py
(which is provided among the starter files)

To help you master while loops, this task requires you to implement a simple game that uses two loops: one to keep asking the player for input until they provide valid input, and another to keep playing a game until the game is complete. The game you will be building is a word-guessing game similar to Wordle.

Overview

In Wordle, the player has 6 guesses to guess a 5-letter word, and each of their guesses must be a real word. After each guess, they are provided with a hint: for each letter in their guess, the game shows whether that letter is in the correct position, present but in the wrong position, or not in the word at all. So for example, if the hidden word is "hello" and the player guesses "loamy", the hints give would be that 'l' and 'o' are in the hidden word (but not in the positions they appeared in the guess) and 'a', 'm', and 'y' are not in the hidden word. The hints are given by coloring in the letters with green for 'correct position', yellow for 'present at a different position' and gray for 'not present.' Since we can't easily color letters in Python, instead we'll give hints in the form of a string of characters with special meanings: '@' for 'correct position,' '*' for 'present at a different position,' and '-' for 'not present.' So the hint for "loamy" if the hidden word is "hello" would be the string: '**---'. Here are a few examples of guesses and hints for 'hello:'

  • 'helps' would give '@@@--'
  • 'jello' would give '-@@@@'
  • 'abcde' would give '----*'

The game we will make has a few differences from standard Wordle:

  1. You are allowed to guess any combination of letters that's the right length, even if your guess is not a word (so 'abcde' is allowed; this makes the game a bit easier as you can quickly guess the entire alphabet).
  2. The word is not required to be 5 letters long. It could be longer or shorter, but each guess must match the length of the hidden word (which is announced). A guess of the wrong length doesn't count against your number of guesses, but also won't show you any information about matching letters.
  3. You can guess as many times as you want. The game doesn't end until you guess the word correctly (although it does keep track of how many guesses that took you; see the examples).

You are required to write three functions that work together to implement the game:

  • letterHints, which determines what hint to give once a word is guessed,
  • getGuess, which asks the player for a guess, and keeps asking until they enter a guess with the correct length, and
  • playGame, which runs the game, asking for guesses using getGuess and showing hints using letterHints until the word has been guessed. (Note that you should not call playGame in your file. Use the shell for testing or comment out any calls to playGame before you submit.

Details on the requirements for each function are as follows:

letterHints

letterHints must be a two-parameter fruitful function which, when given first the hidden word and then a guess from the player, returns the hint string to show to the player for that guess. The hint string is made up of '-', '*', and '@' letters and is the same length as the guess (you can assume that the length of the hidden word will be the same as the length of the guess). The rules for the hint string are as follows:

  • If the guessed letter at a position matches the letter in the hidden word at that position, the hint string will contain an '@' there.
  • If the guessed letter doesn't match at that position, but is present somewhere in the hidden word, the hint string will have a '*'.
  • In places where the guessed letter is not present in the hidden word, the hint string will have a '-'.

These letterHints examples show how it should work, and we have provided tests for letterHints in the test_wordGuesser.py file.

You must use an index loop so that you can access letters in the word and the guess by their positions. (Reminder: An index loop is a loop where the loop variable is an integer which indicates a position within a sequence, instead of being an item from the sequence itself.)

Notes:

getGuess

getGuess must be a one-parameter fruitful function which prompts the player to guess a word using input, and keeps asking for a guess until the player enters a guess that's the right length (since guesses that are the wrong length don't count). The parameter for getGuess is an integer specifying the required length for the guess.

These getGuess examples show how it must work, including the specific text you must use for the prompts and feedback when the input is not the right length. Once the player guesses a word that is the right length, getGuess must return that word.

Note: You must use a while loop, and as an extra goal you should use only a single loop.

playGame

playGame must be a one-parameter non-fruitful function which prints out some introductory text, then repeatedly asks the player to guess a word using getGuess until the player guesses the word correctly, when the game ends and reports the number of guesses the player took, with different text depending on how many guesses were taken.

The parameter for playGame is the word that the player must guess. These playGame examples show how it must work. Note that it must use letterHints to create the hints that it displays, and it must use getGuess. As extra goals, it should only use letterHints once and should use getGuess no more than twice.

Notes:

  • You may not call playGame in your file when you submit it (you can do that temporarily for testing of course. This is because that would require anyone who wants to use any of your functions to first beat the game, which is hard for our automatic testing code, especially since it won't know what the correct answer is.
  • You may not call input in playGame: you must instead use getGuess to request input.
  • We've provided a global variable named INTRO that has the introductory text you'll need to use, so you can just print the contents of that variable at the start of your function without having to re-type all of that text from the examples yourself.
  • Note: You must use a while loop, and as an extra goal you should use only a single loop.
  • Once the player guesses the word, the text 'Congratulations! You guessed it, the word was: ' appears, followed by the hidden word. Then there is one more line of text which depends on how many guesses the player took:
    • If the player guessed the word on the first guess, the message 'Wow, you guessed it in one try!' appears.
    • Otherwise, if the player guessed the word in less than 7 tries, the message: 'Great job! You guessed the word in just N tries.' appears, where N is replaced by the number of guesses used.
    • If the player took 7 or more tries, the message is: 'You guessed the word in N tries.' Here again, N is replaced by the number of guesses.

Testing

The provided file test_wordGuesser.py has tests for each of the required functions. A new version of optimism.py is provided which will skip any tests after one test fails for a specific function, which will hopefully make the test output easier to wade through. You can also run the file before you've finished all of the required functions and tests for functions you haven't defined yet will be skipped.

Random Games

For your enjoyment, we've provided a short list of CS-related terms and a function named playRandomGame. Once your playGame function is done, playRandomGame will allow you to play a game using a random word, so that you don't know what the word is ahead of time.

Notes

Examples

letterHints examples

These examples show how letterHints is supposed to work. Note that the result is returned, not printed. Also note that when the same letter appears multiple times in a guess which is also found at least once in the solution, each instance of that letter will turn into an '@' or a '*' as appropriate.

In []:
letterHints('truism', 'trusty')
Out[]:
'@@@**-'
In []:
letterHints('truism', 'misery')
Out[]:
'***-*-'
In []:
letterHints('truism', 'melody')
Out[]:
'*-----'
In []:
letterHints('truism', 'tattle')
Out[]:
'@-**--'
In []:
letterHints('truism', 'truism')
Out[]:
'@@@@@@'
In []:
letterHints('tattle', 'truism')
Out[]:
'@-----'
In []:
letterHints('misery', 'truism')
Out[]:
'-*-***'
In []:
letterHints('trusty', 'truism')
Out[]:
'@@@-*-'

getGuess examples

These examples show how getGuess should work. Note how the prompt is repeated again and again until the guess is the right length, and that final guess string is the result value.

In []:
getGuess(5)
Prints
Guess a word (5 letters): abcde
Out[]:
'abcde'
In []:
getGuess(3)
Prints
Guess a word (3 letters): abcd You must guess a word with 3 letters. Guess a word (3 letters): ab You must guess a word with 3 letters. Guess a word (3 letters): abc
Out[]:
'abc'

playGame examples

These examples show how playGame should work. The introductory text has been provided for you in the INTRO variable. Note how a hint is printed after every guess except the last (successful) one, and the message at the end depends on the number of guesses taken.

In []:
playGame('goodbye')
Prints
Welcome to guess-that-word! You will guess what the word could be and we will reveal which letters of your guess are correct. If a letter is in the word but in a different location, we'll let you know. '@' means this letter is correct. '*' means this letter is present in a different spot. '-' means this letter is not present. Use the hints to guess the word! The word has 7 letters. Guess a word (7 letters): abcdefg -*-@*-* Guess a word (7 letters): hijklmn ------- Guess a word (7 letters): opqrstu *------ Guess a word (7 letters): vwxyzee ---*-*@ Guess a word (7 letters): goodbye Congratulations! You guessed it, the word was: goodbye Great job! You guessed the word in just 5 tries.
In []:
playGame('hello')
Prints
Welcome to guess-that-word! You will guess what the word could be and we will reveal which letters of your guess are correct. If a letter is in the word but in a different location, we'll let you know. '@' means this letter is correct. '*' means this letter is present in a different spot. '-' means this letter is not present. Use the hints to guess the word! The word has 5 letters. Guess a word (5 letters): hi You must guess a word with 5 letters. Guess a word (5 letters): howdy @*--- Guess a word (5 letters): however You must guess a word with 5 letters. Guess a word (5 letters): light *--*- Guess a word (5 letters): hello Congratulations! You guessed it, the word was: hello Great job! You guessed the word in just 3 tries.
In []:
playGame('hi')
Prints
Welcome to guess-that-word! You will guess what the word could be and we will reveal which letters of your guess are correct. If a letter is in the word but in a different location, we'll let you know. '@' means this letter is correct. '*' means this letter is present in a different spot. '-' means this letter is not present. Use the hints to guess the word! The word has 2 letters. Guess a word (2 letters): hi Congratulations! You guessed it, the word was: hi Wow, you guessed it in one try!

Rubric

Group goals:
 
unknown All functions are documented
Each function you define must include a non-empty documentation string as the very first thing in the function.
 
unknown Do not ignore the results of any fruitful function calls
According to the "Don't waste fruit" principle, every place you call a fruitful function (built-in or custom) you must store the result in a variable, or that function call must be part of a larger expression that uses its return value.
 
unknown Do not create any variables that you never make use of
According to the "Don't waste boxes" principle, every time you create a variable (using = or by defining a parameter for a function) you must also later use that variable as part of another expression. If you need to create a variable that you won't use, it must have the name _, but you should only do this if absolutely necessary.
 
unknown letterHints must return the correct result
The result returned when your letterHints function is run must match the solution result.
 
unknown letterHints must return the correct result
The result returned when your letterHints function is run must match the solution result.
 
unknown getGuess must return the correct result
The result returned when your getGuess function is run must match the solution result.
 
unknown getGuess must print the correct output
The output printed when your getGuess function is run must match the solution output.
 
unknown getGuess must return the correct result
The result returned when your getGuess function is run must match the solution result.
 
unknown getGuess must print the correct output
The output printed when your getGuess function is run must match the solution output.
 
unknown playGame must print the correct output
The output printed when your playGame function is run must match the solution output.
 
unknown playGame must print the correct output
The output printed when your playGame function is run must match the solution output.
 
unknown Define letterHints with 2 parameters
Use def to define letterHints with 2 parameters
 
unknown Use a for loop
Within the definition of letterHints with 2 parameters, use a for loop in exactly one place.
 
unknown Call range
Within the definition of letterHints with 2 parameters, call range in at least one place.
 
unknown Define letterHints with 2 parameters
Use def to define letterHints with 2 parameters
 
unknown Call len
Within the definition of letterHints with 2 parameters, call len in at least one place.
 
unknown Use any kind of loop
Within the definition of letterHints with 2 parameters, use any kind of loop in at least one place.
 
unknown Do not call input
Within the definition of letterHints with 2 parameters, do not call input.
 
unknown Use a return statement
Within the definition of letterHints with 2 parameters, use return _ in at least one place.
 
unknown Define getGuess with 1 parameter
Use def to define getGuess with 1 parameter
 
unknown Use any kind of loop
Within the definition of getGuess with 1 parameter, use any kind of loop in exactly one place.
 
unknown Define getGuess with 1 parameter
Use def to define getGuess with 1 parameter
 
unknown Use a while loop
Within the definition of getGuess with 1 parameter, use a while loop in at least one place.
 
unknown Call input
Within the loop within the definition of getGuess with 1 parameter, call input in at least one place.
 
unknown Use a return statement
Within the definition of getGuess with 1 parameter, use return _ in at least one place.
 
unknown Define playGame with 1 parameter
Use def to define playGame with 1 parameter
 
unknown Use any kind of loop
Within the definition of playGame with 1 parameter, use any kind of loop in exactly one place.
 
unknown Call getGuess
Within the definition of playGame with 1 parameter, call getGuess in at least one and at most 2 places.
 
unknown Call letterHints
Within the definition of playGame with 1 parameter, call letterHints in exactly one place.
 
unknown Define playGame with 1 parameter
Use def to define playGame with 1 parameter
 
unknown Use a while loop
Within the definition of playGame with 1 parameter, use a while loop in at least one place.
 
unknown Call getGuess
Within the definition of playGame with 1 parameter, call getGuess in at least one place.
 
unknown Call letterHints
Within the definition of playGame with 1 parameter, call letterHints in at least one place.
 
unknown Do not call input
Within the definition of playGame with 1 parameter, do not call input.
 
unknown Do not use a return statement
Within the definition of playGame with 1 parameter, do not use return _.