Part 1: Loading and processing phrases
For your hangman game, you will need some phrases for the user to guess. The first step is to load the phrases from a file, initialize the attributes of each phrase, and sort them by difficulty. To verify that this part is working, you will temporary display all of the phrases.
Phrase that has three members:
textthat will store the text of a phrase.
guessesRequiredthat will contain the minimum number of guesses required. Note that this member can never be negative.
isUsedthat will be set from
trueif and when a phrase is used.
Create the following functions:
uniqueLetterCount: Accepts a constant reference to a
stringand returns the number of unique letters in that
string. Only letters (‘A’ through ‘Z’ and ‘a’ through ‘z’) count as letters. The function is case insensitive which means that ‘A’ and ‘a’ only count as one unique letter. For example, the phrase,
"A wolf in sheep's clothing"contains 14 unique letters. This function will be used to determine the correct guesses required to get the phrase.
Hints: One approach would be to use a
stringto store the unique lowercase letters you find. Use
string‘s find function to see if a character from the input
stringexists in the unique letters
string. After finding all the unique letters, return the length of the unique letters
loadPhrasesFromFile: Reads in a file where each line is the text of a phrase. Initializes an array of
Phrases. This function accepts (1) the filename as a
const stringreference, (2) an array of
Phrases, and (3) the array length. The function should return the number of
Phrases read from the file. The guessesRequired member should be set to the value returned by
isUsedmember should be initialized to
false. The function should read in phrases from the file up to the end of the file or the array size (whichever comes first). Then, return the number of phrases read from the file.
sortPhrases: Uses the Selection Sort algorithm to sort the array of
Phrases by their
guessesRequired. See the Chapter 8 lecture notes/videos (or pages 545 – 549 of your textbook) for the algorithm and some code to get you started. The function should include the array length as the second parameter and only sort values within the bounds of the array length. You may create additional functions for finding the max index and swapping Phrases split this problem into subproblems.
printPhrases: Outputs to the screen an array of phrases. The output should be formatted such that there is one
Phraseper line, with the following order for phrase members: (1)
text, and (3)
isUsedshould be output as a human readable
"The output should be in an aligned table format that matches this sample output:
Sample Output # Phrase State 13 A bird in the hand is worth two in the bush. unused 9 A broken heart unused 8 A cross to bear unused 14 A drop in the bucket unused 11 A fly in the ointment unused 8 A graven image unused 15 A house divided against itself cannot stand. unused 8 A labor of love unused 14 A leopard cannot change its spots unused 12 A man after his own heart unused 12 A multitude of sins unused 11 A nest of vipers unused 11 A sign of the times unused 14 A wolf in sheep’s clothings unused 11 A thorn in the flesh unused 11 All things must pass unused 11 All things to all men unused 13 Am I my brother’s keeper? unused 9 An eye for an eye, a tooth for a tooth unused 10 As old as Methuselah unused 9 As old as the hills unused 9 As white as snow unused 11 You reap what you sow. unused 8 Ashes to ashes dust to dust unused 9 At his wits end unused 11 Baptism of fire unused 14 Be fruitful and multiply. unused 14 Beat swords into plowshares. unused 8 Bite the dust unused 13 Blessed are the peacemakers. unused 7 Born again unused 10 Breath of life unused 13 By the skin of your teeth unused 14 Can a leopard change its spots? unused 14 Cast bread upon the waters. unused 11 Cast the first stone. unused 14 Charity begins at home. unused 11 Coat of many colors unused 17 Don’t cast your pearls before swine. unused 5 Dust to dust unused 11 Eat drink and be merry. unused 4 Eye to eye unused 12 Faith that moves mountains unused 9 Fall from grace unused 8 Fight the good fight. unused 12 Fire and brimstone unused 10 Flesh and blood unused 13 For everything there is a season unused 16 Forgive them for they know not what they do unused 10 Gird your loins. unused 11 Go the extra mile. unused 8 Heart’s desire unused 10 Holier than thou unused 13 In the beginning was the word. unused 13 In the twinkling of an eye unused 13 It’s better to give than to receive unused 9 Labour of love unused 12 Lamb to the slaughter unused 6 Land of Nod unused 14 Let he who is without sin cast the first stone. unused 12 To everything there is a season. unused 13 Jumping Jehosaphat! unused
Test your code: The main function should use these functions to do the following in order: (1) read in the file, (2) output the phrases to the screen, (3) sort the phrases, and (4) output the phrases again now that they are sorted. For the actual game, you will not print the phrases, but you should do this temporary to make sure everything is working. After removing the calls to
printPhrases, keep this function defined in your code so you can use it for debugging as needed in the future.
Part 2: Print out the phrase with an underscore for each unguessed letter.
Create a function named
phraseWithBlanks that accepts a constant reference to the text from a phrase and a constant reference to a string of correctly-guessed lowercase letters. The function will return a string representing the phrase where every unguessed letter is represented by an underscore character and each character is separated by a space. Non-letter characters should be output as is. For example, if the phrase text is
"It's time to eat!" and the correctly guessed string is
"io", then the function should return
"I _ ' _ _ i _ _ _ o _ _ _ !".
Hint 1: You may find that the
tolower function is helpful, which can be used if you include the
cctype. Also, it may be helpful to create an
isLetter function that returns
true if a single character is a letter (or use
Hint 2: Use
string‘s find function to see if a character in the phrase-text
string exists in the correctly-guessed letters
Part 3: Select a random phrase based on the difficulty level
Create a function named
getDifficultyLevel that displays three difficulty levels: (1) Easy, (2) Medium, and (3) Hard. The function should ask the user to enter a number for the difficulty level they wish to play at. The function should then validate the user input, making sure that it is an integer between 1 and 3 inclusive. If it is not, the function should prompt the user for input again until the input number is valid. When a valid input is entered, the function should return the requested difficulty level minus 1 (e.g., if the user inputs 1, return 0).
Use the following example output for how the prompts should be formatted.
Sample Output (user input is in yellow)Difficulty levels: 1 Easy 2 Medium 3 Hard Pick a difficulty level (1 to 3): 4 Please choose a difficulty level between 1 and 3: four again Please choose a difficulty level between 1 and 3: 2
Optional Extension: Instead of using an
int type for difficulty, you could create new enum type called
DifficultyLevel with the values
getDifficultyLevel return a value from this enum.
Create another function, named
randomPhraseIndex that accepts three parameters: (1) the difficulty level, (2) a const array of
Phrases, and (3) the length of the array (i.e., the phrase count). The function should produce a random number that will be the index of the next
Phrase to be guessed. If the difficulty level is EASY (0), the random number should fall within the first third of the indices of initialized
Phrases in your sorted Phrase array. Likewise, if the difficulty level is MEDIUM (1), the number should fall in the second third of valid indices. The HARD difficulty level should include the last third of the phrases and any phrases that do not divide evenly into 3 groups. (See the posted video on random numbers for information about how to do this step.)
Create a loop in
randomPhraseIndex that checks if the
Phrase at the random index is unused
(isUsed == false). Keep generating new random indices until the index points to an unused
Phrase. When the loop ends, return the random index of the unused phrase.
main function, seed the random number generator and call these two functions. Do NOT seed the random number generator in another function; we wan’t to make sure we only set the seed once and other function may be called multiple times. Add some temporary code to main to make sure everything is working correctly.
Part 4: The game loop
This step is where everything comes together into a playable game. Create a function called
runGame that accepts a reference to a
Phrase. Create a
do...while loop that continues while the number of incorrect guesses is less than 5 and the number of correct guesses is less than the
guessesRequired. In that loop first call the
drawGallows function (see starter code), then print the phrase with blanks, then prompt the user to enter a guess. After getting the user’s input, output 20 newlines to “clear” the screen. Then, consider the following conditions based on the guess:
- If the guess is not a letter, output an error message. For example,
"'!' is not a valid guess. Please enter a letter."
- Otherwise, if the guess has already been guessed, output an error message in the following format:
"You have already guessed an 'e'."
- Otherwise, if the guess is in the phrase, output “Good guess” and store the guess in a sting of correct guesses.
- Otherwise, output the message, “Sorry, bad guess.” and add the guess in a string of incorrect guesses.
After the loop, draw the gallows one more time and the phrase (with blanks as needed). Depending on the number of incorrect guesses, output either
"You Win!" or
"You're Dead! The phrase was:" followed by the phrase.
Call this function from main and make sure everything is working correctly.
Hint: It may be helpful to store the current phrase’s text as an all-lowercase string to be used in comparisons. You may want to create a function named
toLowerCase that accepts a constant reference to a string and returns that string, but with all lowercase letters.
Part 5: Allow the user to play multiple times per run.
do...while loop to your main function that includes the necessary code to:
- Select a phrase at random based on the chosen difficulty level
- Run the game with the current phrase.
- Mark the current phrase as used and maintain a count of the number of phrases asked.
- If there are more phrases to be guessed at that difficulty level, ask the user if he/she would like to play again with this prompt,
"Would you like to play again? (y/n): "
The loop should continue while there are more phrases to be guessed and the user inputs a ‘y’ to play again.
Test your code to make sure it works like the demo video. You have created your own commandline game!
ACTIONSSubmit ProjectThe due date for this project has passed. Your instructors can give you an extension if they see fit.