How to solve word generation error in Hangman Game? - python

Q.Building Hangman Game. In the game of Hangman, the player only has 6 incorrect guesses (head, body, 2 legs, and 2 arms) before they lose the game. We loaded a random word list and picked a word from it. Then we wrote the logic for guessing the letter and displaying that information to the user. In this exercise, we have to put it all together and add logic for handling guesses.
So, I made the program with some help but stil there is a silly little problem coming that is the generation of a random word.
Please tell what I am doing wrong and if you would run this program that would help you better understand what I am saying.
import random
def generate():
Words = []
with open('sowpods.txt', 'r') as f:
line = f.readline().strip()
Words.append(line)
while line:
line = f.readline().strip()
Words.append(line)
index = random.randint(0, len(Words) - 1)
return Words[index]
def ask_user_for_next_letters():
letter = input("Guess Your Letter: ")
return letter.strip().upper()
def generate_word_string(word, letter_guessed):
output = []
for letter in word:
if letter in letter_guessed:
output.append(letter.upper())
else:
output.append("_")
return " ".join(output)
print("Welcome To Hangman!")
if __name__ == "__main__":
Secret = generate()
letter_to_guess = set(Secret)
correct_letters = set()
incorrect_letters = set()
num_guesses = 0
while (len(letter_to_guess) > 0) and num_guesses < 6:
guess = ask_user_for_next_letters()
#Checks If We Already Guessed That Letter
if guess in correct_letters or guess in incorrect_letters:
print("You Already Guessed That!")
continue
#If The Guess Was Correct
if guess in letter_to_guess:
#Update The letter_to_guess
letter_to_guess.remove(guess)
#Update The Correct Letters Guessed
correct_letters.add(guess)
else:
incorrect_letters.add(guess)
#Only Update The Number Of Guesses
#If You Guess Incorrectly
num_guesses += 1
word_string = generate_word_string(Secret, correct_letters)
print(word_string)
print("You Have {} Guesses Left".format(6 - num_guesses))
#Tell The User They Have Won Or Lost
if num_guesses < 6:
print("Congratulations! You Correctly Guessed The Word {}!".format(Secret))
else:
print("Loser!".format(Secret))

Modifications
Corrects routine generate to provide random words.
Always convert users input to uppercase
Convert selected word to upper case
slight change in variable naming so it conforms to PEP 8 (i.e. 'secret' rather than 'Secret')
Code
import random
def generate():
words = []
with open('sowpods.txt', 'r') as f:
for line in f:
line = line.strip()
if line:
words.append(line)
return random.choice(words).upper()
def ask_user_for_next_letters():
letter = input("Guess Your Letter: ")
return letter.strip().upper()
def generate_word_string(word, letter_guessed):
output = []
for letter in word:
if letter in letter_guessed:
output.append(letter.upper())
else:
output.append("_")
return " ".join(output)
if __name__ == "__main__":
print("Welcome To Hangman!")
secret = generate()
letter_to_guess = set(secret)
correct_letters = set()
incorrect_letters = set()
num_guesses = 0
while (len(letter_to_guess) > 0) and num_guesses < 6:
guess = ask_user_for_next_letters()
#Checks If We Already Guessed That Letter
if guess in correct_letters or guess in incorrect_letters:
print("You Already Guessed That!")
continue
#If The Guess Was Correct
if guess in letter_to_guess:
#Update The letter_to_guess
letter_to_guess.remove(guess)
#Update The Correct Letters Guessed
correct_letters.add(guess)
else:
incorrect_letters.add(guess)
#Only Update The Number Of Guesses
#If You Guess Incorrectly
num_guesses += 1
word_string = generate_word_string(secret, correct_letters)
print(word_string)
print("You Have {} Guesses Left".format(6 - num_guesses))
#Tell The User They Have Won Or Lost
if num_guesses < 6:
print("Congratulations! You Correctly Guessed The Word {}!".format(secret))
else:
print("Loser!".format(secret))

Related

How do I make it so every time I play_again in my hangman game, a new word is generated?

Basically the title. I want my hangman game to generate a new random word from an imported file list every time I play again. However, when I do it it simply utilizes the same word as before. Here is the code.
import random
with open("English_Words", "r") as file:
allText = file.read()
words = list(map(str, allText.split()))
word = random.choice(words)}
def play_again():
print("Do you want to play again (Yes or No)")
response = input(">").upper()
if response.startswith("Y"):
return True
else:
return False
def singleplayer():
guessed = False
word_completion = "_" * len(word)
tries = 6
guessed_letters = []
while not guessed and tries > 0:
print(word_completion)
print(hangman_error(tries))
print(guessed_letters)
guess = input("Guess a letter:").lower()
if guess in guessed_letters:
print("You have already guessed that letter.")
elif guess not in word:
print("[INCORRECT] That letter is not in the word!")
guessed_letters.append(guess)
tries -= 1
if tries == 0:
print("You ran out of tries and hanged the man! The word or phrase was: " + str(word))
elif guess in word:
print("[CORRECT] That letter is in the word!")
guessed_letters.append(guess)
word_as_list = list(word_completion)
indices = [i for i, letter in enumerate(word) if letter == guess]
for index in indices:
word_as_list[index] = guess
word_completion = "".join(word_as_list)
if "_" not in word_completion:
guessed = True
if tries == 0:
print("You ran out of tries and hanged the man! The word or phrase was: " + str(word))
if "_" not in word_completion:
guessed = True
if guessed:
print("You win, the man was saved! The word was:" + str(word))
while True:
singleplayer()
if play_again():
continue
else:
break
You need to call word = random.choice(words) inside of your singleplayer() function. Preferrably at the top, either right above or right below the guess = False line.
This way, you're program is going to call that random choice line everytime you call the singleplayer function.
def singleplayer():
word = random.choice(words)
guessed = False

Hangman game letter guessing

that plays hangman game.
I guess a have an error in my guessWord(word) function, because its not working properly, and I'm not getting why?
the file for readDictionary contains rows of words for the game. but in the main code words can also be used.
current output:
Welcome to the hangman game.
You will be guessing words, one letter at a time
Guess a letter
a
Would you like to guess a new word? Y/N: y
Guess a letter
h
Would you like to guess a new word? Y/N: g
You guessed 2 words out of 2
desired output:
Your guess so far: -------
Guess a letter from the secret word: a
Good guess;
Your guess so far: -A----A
Guess a letter from the secret word: e
Wrong guess
--------
|
Your guess so far: -A----A
Guess a letter from the secret word: s
Wrong guess
--------
|
O
#and so on…
here are the parameters to do:
readDictionary() which reads the accompanying file “dictionary.txt” and returns a list of all the words appearing in the file.
• guessWord(word) which runs the user interface for guessing the word passed as argument, as described above. guessWord() calls hangmanSketch() with the appropriate argument, whenever a wrong guess is entered by the player.
Note that, even though all the words in the are in all-capital letters, the player should be able to enter the guesses in lower case.
The function returns True, if the player manages to guess the whole word before making 8 wrong guesses. The function returns False, if the player makes 8 wrong guesses and does not guess the whole word.
Below is an extract of a sample run of the whole application, showing the interface for successfully and unsuccessfully guessing words.
code:
from random import choice
def readDictionary():
file = open("dictionary.txt", "r")
lines = file.readlines()
return list(lines)
def hangmanSketch(n):
if n <= 0:
pic = ''' --------\n'''
return pic
pic = hangmanSketch(n-1)
if n == 1:
pic += ''' |\n'''
elif n == 2:
pic += ''' O\n'''
elif n == 3:
pic += '''_/'''
elif n == 4:
pic += '''|'''
elif n == 5:
pic += '''\_ \n'''
elif n == 6:
pic += ''' |\n'''
elif n == 7:
pic += '''_/'''
elif n == 8:
pic += ''' \_ \n'''
return pic
def guessWord(word):
while True:
print("Guess a letter")
userGuess = input()
userGuess = userGuess.lower()
if len(userGuess) != 1:
print("Please enter a single letter")
elif userGuess in word:
print("letter already guessed, try another")
else:
return userGuess
def main():
print("Welcome to the hangman game.")
print("You will be guessing words, one letter at a time")
words = readDictionary()
words = ['ABANDON', 'INQUIRING', 'LACROSSE', 'REINITIALISED'] # use this list if you don't manage to implement readDictionary()
nAttemptedWords = 0
nGuessedWords = 0
play = "Y"
while play == "Y":
secretWord = choice(words) # random choice of one word from the list of words
nAttemptedWords += 1
if guessWord(secretWord):
nGuessedWords += 1
play = input("Would you like to guess a new word? Y/N: ")
play = play.upper()
print("You guessed", nGuessedWords, "words out of", nAttemptedWords)
if __name__ == "__main__":
main()
I suggest you having one while for iterating between words and inner while for iterating through player's guesses:
import random
WORDS = ['abandon', 'inquiring', 'lacrosse', 'reinitialised']
def guessed_word(word, guessed_letters):
""" Build guessed word. E.g.: "--c--r" """
result = ''
for letter in word:
if letter in guessed_letters:
result += letter
else:
result += '-'
return result
print('Welcome to the hangman game.')
print('You will be guessing words, one letter at a time')
play = 'y'
while play == 'y':
word = random.choice(WORDS)
guessed_letters = []
hp = 8
while True:
print(f'Your guess so far: {guessed_word(word, guessed_letters)}')
letter = input('Guess a letter from the secret word: ')
if letter in list(word):
print('Good guess')
guessed_letters.append(letter)
else:
print('Wrong guess')
hp -= 1
if hp == 0:
print('You loose!')
break
elif len(guessed_letters) == len(set(word)):
print(f'You win! The word is: {word}')
break
play = input('Would you like to guess a new word? y/n: ')
Output:
Welcome to the hangman game.
You will be guessing words, one letter at a time
Your guess so far: --------
Guess a letter from the secret word: a
Good guess
Your guess so far: -a------
Guess a letter from the secret word: b
Wrong guess
Your guess so far: -a------
Guess a letter from the secret word: c
Good guess
Your guess so far: -ac-----

how to return a string from a for loop instead of printing out one by one

Im trying to make my for loop return a string of the whole word with a dash or each letter depending on guess_letters instead of print out each letter one by one for my hangman game.
Ive tried to print letter as a string, return letter then set a variable to that function then print the variable.
import random
words = ['apple','python','parent']
def randomword(words):
return random.choice(words)
chosenword = randomword(words)
tries = 10
guess_letters = []
def dashshow(guess_letters):
for letter in chosenword:
if letter in guess_letters:
return str(letter)
string_letter = dashshow(guess_letters)
print(string_Letter)
else:
return '-'
dash_letter = dashshow(guess_letters)
print(dash_letter)
def playgame(tries):
while tries != 0 and "_" in chosenword:
print(f"You have {tries} tries left")
guess = str(input("Guess a letter of the word")).lower()
guess_letters.append(guess)
if guess in chosenword:
print("You got a letter correct!")
turns -= 1
else:
print("That letter is not in the word")
turns -= 1
playgame(tries)
I thought it would print out the string with dashes or letters depending on the guessed_letters list but it doesn't print anything.
here is way you can. just modify as you need.Also, You can compare your code with this one. to find mistake.
import random
words = ['apple','python','parent']
def randomword(words):
return random.choice(words)
chosenword = randomword(words)
print (chosenword) #this is random word you can delete this line.
tries = 10
guess_letters = []
def dashshow(guess_letter):
guess_letters.append(guess_letter)
print(guess_letters) # just to debug you can remove.
if len(guess_letters) == len(chosenword):
print("You Won Dear!")
exit()
def playgame(tries):
while tries != 0 :
print(f"You have {tries} tries left")
guess = str(input("Guess a letter of the word:> ")).lower()
if any(guess in s for s in chosenword):
print("You got a letter correct!")
dashshow(guess)
tries -= 1
else:
print("That letter is not in the word")
tries -= 1
playgame(tries)

HANGMAN assignment python

For an assignment I need to write a basic HANGMAN game. It all works except this part of it...
The game is supposed to print one of these an underscore ("_") for every letter that there is in the mystery word; and then as the user guesses (correct) letters, they will be put in.
E.G
Assuming the word was "word"
User guesses "W"
W _ _ _
User guesses "D"
W _ _ D
However, in many cases some underscores will go missing once the user has made a few guesses so it will end up looking like:
W _ D
instead of:
W _ _ D
I can't work out which part of my code is making this happen. Any help would be appreciated! Cheers!
Here is my code:
import random
choice = None
list = ["HANGMAN", "ASSIGNEMENT", "PYTHON", "SCHOOL", "PROGRAMMING", "CODING", "CHALLENGE"]
while choice != "0":
print('''
******************
Welcome to Hangman
******************
Please select a menu option:
0 - Exit
1 - Enter a new list of words
2 - Play Game
''')
choice= input("Enter you choice: ")
if choice == "0":
print("Exiting the program...")
elif choice =="1":
list = []
x = 0
while x != 5:
word = str(input("Enter a new word to put in the list: "))
list.append(word)
word = word.upper()
x += 1
elif choice == "2":
word = random.choice(list)
word = word.upper()
hidden_word = " _ " * len(word)
lives = 6
guessed = []
while lives != 0 and hidden_word != word:
print("\n******************************")
print("The word is")
print(hidden_word)
print("\nThere are", len(word), "letters in this word")
print("So far the letters you have guessed are: ")
print(' '.join(guessed))
print("\n You have", lives,"lives remaining")
guess = input("\n Guess a letter: \n")
guess = guess.upper()
if len(guess) > 1:
guess = input("\n You can only guess one letter at a time!\n Try again: ")
guess = guess.upper()
while guess in guessed:
print("\n You have already guessed that letter!")
guess = input("\n Please take another guess: ")
guess = guess.upper()
guessed.append(guess)
if guess in word:
print("*******************************")
print("Well done!", guess.upper(),"is in the word")
word_so_far = ""
for i in range (len(word)):
if guess == str(word[i]):
word_so_far += guess
else:
word_so_far += hidden_word[i]
hidden_word = word_so_far
else:
print("************************")
print("Sorry, but", guess, "is not in the word")
lives -= 1
if lives == 0:
print("GAME OVER! You ahve no lives left")
else:
print("\n CONGRATULATIONS! You have guessed the word")
print("The word was", word)
print("\nThank you for playing Hangman")
else:
choice = input("\n That is not a valid option! Please try again!\n Choice: ")
You have hidden_word = " _ " * len(word)
This means that at start for a two letter word, you have [space][underscore][space][space][underscore][space].
When you then do word_so_far += hidden_word[i], for i = 0, you will append a space, not an underscore.
The quickest fix would seem to be:
Set hidden_word to just be _'s (hidden_word = " _ " * len(word))
When you print out the word, do
hidden_word.replace("_"," _ ") to add the spaces around the underscores back
#Foon has showed you the problem with your solution.
If you can divide your code up into small functional blocks, it makes it easier to concentrate on that one task and it makes it easier to test. When you are having a problem with a specific task it helps to isolate the problem by making it into a function.
Something like this.
word = '12345'
guesses = ['1', '5', '9', '0']
def hidden_word(word, guesses):
hidden = ''
for character in word:
hidden += character if character in guesses else ' _ '
return hidden
print(hidden_word(word, guesses))
guesses.append('3')
print(hidden_word(word, guesses))
Below code solves the problem.you can do some modifications based on your requirement.If the Guessed letter exists in the word.Then the letter will be added to the display variable.If not you can give a warning .But note that it might tempt you to write ELSE statement inside the for loop(condition:if guess not in word).If you do like that then the object inside the Else statement will be repeated untill the For loop stops.so that's why it's better to use a separete IF statement outside the for loop.
word="banana"
display=[]
for i in word:
display+="_"
print(display)
while True:
Guess=input("Enter the letter:")
for position in range(len(word)):
if Guess==word[position]:
display[position]=word[position]
print(display)
if Guess not in word:
print("letter Doesn't exist")

Python hangman replacing

So I'm writing a hangman program and I'm having trouble getting the current guesses to display as underscores with the correct letters guessed replacing an underscore. I can get the function to work once (thats the insert_letter function) and I know its just replacing every time it goes through the loop, but I can't return the new current without quitting the loop so if someone could offer another way to get the guesses to keep updating that would be great!
def insert_letter(letter, current, word):
current = "_" * len(word)
for i in range (len(word)):
if letter in word[i]:
current = current[:i] + letter + current[i+1:]
return current
def play_hangman(filename, incorrect):
words = read_words(filename)
secret_word = random.choice(words)
num_guess = 0
letters_guessed = set()
letter = input("Please enter a letter: ")
while num_guess < incorrect:
letter = input()
if letter in secret_word:
current = insert_letter(letter, current, secret_word)
print(current)
else:
num_guess += 1
current = "_" * len(secret_word)
print(current)
letters_guessed.add(letter)
You didn't show the code for your insert_letter() function so I wrote an alternative -- display_remaining(). Give this a try:
import random, sys
def play_hangman(filename, incorrect):
words = read_words(filename)
secret_word = random.choice(words)
num_guess = 0
letters_guessed = set()
while num_guess < incorrect:
letter = input("Please enter a letter: ")
letters_guessed.add(letter)
current = display_remaining(secret_word, letters_guessed)
print(current)
if not letter in secret_word:
print("Incorrect guess.")
num_guess += 1
if not '_' in current:
print("Congratulations! You've won!")
sys.exit(0)
print("Sorry. You've run out of guesses. Game over.")
def display_remaining(word, guessed):
replaced = word[:]
for letter in word:
if (not letter == '_') and letter not in guessed:
replaced = replaced.replace(letter, '_', 1)
return replaced
def read_words(filename):
with open(filename, 'rU') as f:
return [line.strip() for line in f]
if __name__ == '__main__':
play_hangman('words.txt', 6)
NOTE: With this implementation, your words file shouldn't have any words containing the underscore character.

Categories

Resources