Decomposition
It can be tempting to make a game like this without using subroutines, and while it is possible, the point of this challenge is to use all the skills you have used up to now. The first step is to decompose the problem.
Make a list of the seoarate tasks you can break a game of hangman down into then check below for the list we will be using this time.
The subroutines we will create in this instance will be: get_word(); make_mask(); get_letter(); check_letter(); check_winner()
make_mask()
For this we are going to make a string of asterisks as long as the chosen word and return that mask to the main program.
def make_mask(word): mask = "*" * len(word) return mask |
get_letter()
I think its important to consider the users when making games and so we will include a check that the user is not choosing a letter they have already chosen before. To do this pass a list of chosen letters to the
subroutine and if the user enters a letter they have already selected then make them choose again. This will stop players losing a life for re-guessing the same letter. At the end of this subroutine return the chosen
letter and the updated used letters list
def get_letter(guessed): letter = input("Guess one of the missing letters: ") while letter in guessed:
print("You already guessed that letter.") letter = input("Guess one of the missing letters: ")
guessed.append(letter) return letter, guessed |
check_letter()
This process reuires a number of elements from the main game to be passed in: the chosen letter, the word, the current mask and the number of lives the player has. The subroutine needs to update the mask if the letter
matches the character in the same position in the word e.g. if the word is "hello" and the current mask is "h****" and the user guesses l so the returned mask is "h*ll*". The subroutine also has to reduce the players
lives by 1 if no letter in the word matches the chosen letter. When finished the subroutine should return the updated mask and lives.
def check_letter(letter, mask, word, lives): new_mask = "" change = False for i in range(len(word)):
if word[i] == letter: new_mask += letter
change = True else:
new_mask += mask[i] if change == False: lives -= 1
return new_mask, lives |
Main program
Now we can combine all our tried and tested subroutines to make the overall main program.
lives = 7 guessed = [] word = get_word() mask = make_mask(word) while lives > 0 and mask != word: print(f"{mask}") letter, guessed = get_letter(guessed)
mask, lives = check_letter(letter, mask, word, lives) show_state{lives} check_win(lives, word) |