why is my while loop running print _ forever? - python

I think the problem is with my second while loop. It keeps printing the _ after I press enter to run the game. I'm not sure how the condition isn't being met or where to add a break. I have tried changing the indentation of my else: and when I do the loop won't run at all.
import random
#make a list of words
words = [
'apple',
'banana',
'orange',
'coconut',
'strawberry',
'lime',
'grapefruit',
'lemon',
'kiwi',
'blueberry',
'melon'
]
while True:
start = input("Press enter/return to start, or Q to quit")
if start.lower() == 'q':
break
#pick rand word
secret_word = random.choice(words)
bad_guesses = []
good_guesses = []
while len(bad_guesses) < 7 and len(good_guesses) != len(list(secret_word)):
#draw guessed letters, spaces, and strikes
for letter in secret_word:
if letter in good_guesses:
print(letter, end='')
else:
print('_', end='')
print('')
print('Strikes: {}/7'.format(len(bad_guesses)))
print('')
#take guess
guess = input("Guess a letter: ").lower()
if len(guess) != 1:
print("You can only guess a single letter!")
continue
elif guess in bad_guesses or guess in good_guesses:
print("You already guessed that letter!")
continue
elif not guess.isalpha():
print("You can only guess letters!")
continue
if guess in secret_word:
good_guesses.append(guess)
if len(good_guesses) == len(list(secret_word)):
print("You Win! The word was {}".format(secret_word))
break
else:
bad_guesses.append(guess)
else:
print("You didn't get it! My secret word was {}".format(secret_word))

Here is a working version of your code. Just corrected the necessary parts, but undoubtedly you should consider writing a more clean, and better indented code.
import random
# make a list of words
words = [
'apple',
'banana',
'orange',
'coconut',
'strawberry',
'lime',
'grapefruit',
'lemon',
'kiwi',
'blueberry',
'melon'
]
while True:
start = input("Press enter/return to start, or Q to quit")
if start.lower() == 'q':
break
bad_guesses = []
good_guesses = []
# pick rand word
secret_word = random.choice(words)
while len(bad_guesses) < 7 and len(good_guesses) != len(list(secret_word)):
# draw guessed letters, spaces, and strikes
for letter in secret_word:
if letter in good_guesses:
print(letter, end='')
else:
print('_', end='')
print('\Bad guesses: {}/7\n'.format(len(bad_guesses)))
# take guess
guess = input("Guess a letter: ").lower()
if len(guess) != 1:
print("You can only guess a single letter!")
continue
elif guess in bad_guesses or guess in good_guesses:
print("You already guessed that letter!")
continue
elif not guess.isalpha():
print("You can only guess letters!")
continue
if guess in secret_word:
good_guesses.append(guess)
else:
bad_guesses.append(guess)
if len(good_guesses) == len(set(secret_word)):
print("You Win! The word was {}".format(secret_word))
break
print("You didn't get it! My secret word was {}".format(secret_word))

In the block with this condition:
while len(bad_guesses) < 7 and len(good_guesses) != len(list(secret_word)):
nothing changes about the bad_guesses, good_guesses, or secret_word variables. That means you'll just keep retrying it forever.
You probably wanted an if not a while in that case.

Related

I only can type 1 letter , how do I let the code know that 2 or more letters are also okay?

import random
from typing import List
words = [ 'apple', 'tree', 'python', 'bench', 'float' ]
word = random.choice(words)
guesses= []
letter_storage = []
f = "Do you want to play?"
a = ["yes","no"]
max_fails = []
def print_word_to_guess(letters: List):
print("{0}".format(" ".join(letters))) # need to display _ _ _ _ instead of ['_', '_', '_', '_', '_']
def input_choice(f:str,a:list[str])->str:
if f in a:
if f == "yes":
a = "yes"
elif f == "no":
print("ok no")
elif f not in a:
while f not in a:
f = input("Invalid answer. Try again")
if f in a:
if f == "yes":
a = "yes"
elif f == "no":
print("ok no")
def shape(word:str,guesses:str)->str:
for letter in word:
guesses.append("_ ")
def hangman(word:str,max_fails:int):
max_fails = int(input("Number of allowed mistakes: "))
while max_fails> 0:
guess = input("make a guess:")
if guess in letter_storage:
print("mistakes left:",max_fails,",you already guessed that letter!")
else:
letter_storage.append(guess)
if guess in word :
for x in range(0, len(word)):
if word[x] == guess:
guesses[x] = guess
print_word_to_guess(guesses)
if not '_ ' in guesses:
print("You won!","The word was:",word)
break
else:
max_fails -= 1
print(max_fails,"mistakes left")
if max_fails == 0:
print("You lost :( The word was",word)
input_choice(input("Do you want to play? [yes / no]"),("yes","no"))
shape(word,guesses)
hangman(word,max_fails)
Here is my little hangman game.
The code recognizes that the multiple letters are in the word but it doesnt add them to the spaces.
I would like that multiple letters are also accepted so when you already guessed app u can also add le
to finish the game. How can I implement this into my code ?
You can save the guess to a variable guess_str, then loop through all the letters of the guess with for guess in guess_str and run your code logic again:
def hangman(word: str, max_fails: int):
max_fails = int(input("Number of allowed mistakes: "))
while max_fails > 0:
guess_str = input("make a guess:")
for guess in guess_str:
if guess in letter_storage:
print("mistakes left:", max_fails, ",you already guessed that letter!")
else:
letter_storage.append(guess)
if guess in word:
for x in range(0, len(word)):
if word[x] == guess:
guesses[x] = guess
print_word_to_guess(guesses)
if not "_ " in guesses:
print("You won!", "The word was:", word)
break
else:
max_fails -= 1
print(max_fails, "mistakes left")
if max_fails == 0:
print("You lost :( The word was", word)

Guess word game in python needs to end

How do I end this game? If the whole word is guessed it's over or you loose all life, but I am unable to end it if someone guesses all letters one by one.
secret_word = "something".upper()
lifes = u'\u2764'
total_lifes = 5
print("You have 5 lifes in total to guess the answer")
guess = None
for_list = "?"*len(secret_word)
my_list = list(for_list)
def change_user_output(value):
for j in range(0, len(secret_word)):
if (value == secret_word[j]):
my_list[j] = value
new_user_output = " ".join(my_list)
print(new_user_output)
while total_lifes > 0:
print(lifes * total_lifes)
print("Guess any letter : ")
guess = input().upper()
if(guess == secret_word):
print("WOW that is correct, the secret word is %s"%secret_word)
break
if(guess in secret_word):
print("You guessed it right %s is in SECRET WORD"%guess)
change_user_output(guess)
else:
print("There is no such letter in the SECRET WORD, you loose a life")
change_user_output(guess)
total_lifes -= 1
if total_lifes == 0:
print("You've lost all lifes, GAME OVER FOR YOU")
print("The SECRET WORD was : %s"%"".join(secret_word))
The problem is that if (guess == secret_word): will always be False since guess is a single letter and it gets replaced by a new input every iteration guess = input().upper(). So your loop will never quit in case of correct guess, it will quit only when you finish the lives.
You could add the following to check if the guessed letters match those in the secret word:
if(guess in secret_word):
print("You guessed it right %s is in SECRET WORD"%guess)
change_user_output(guess)
# New code below here.
if set(list(secret_word)) == set(my_list):
print("WOW that is correct, the secret word is %s"%secret_word)
break
You create a set of all letters needed. You add each guessed letter to another set.
If the set of needed letters is a subset of the guessed letters set, you are done:
secret_word = "apple".upper()
lifes = '#'
total_lifes = 5
print("You have 5 lifes in total to guess the answer")
guess = None
for_list = "?"*len(secret_word)
my_list = list(for_list)
characters_needed = set(secret_word) # set of all letters needed
characters_guessed = set() # set of guessed letters
len_secret = len(secret_word)
def change_user_output(value):
for j in range(0, len(secret_word)):
if (value == secret_word[j]):
my_list[j] = value
new_user_output = " ".join(my_list)
print(new_user_output)
while total_lifes > 0:
print(lifes * total_lifes)
print("Guess any letter : ")
guess = input().upper()
# check for correct lenghts of input:
if len(guess) not in (1,len_secret):
print("1 letter or the whole word! Try again.")
continue
if(guess == secret_word):
print("WOW that is correct, the secret word is {}".format(secret_word))
elif(len(guess) > 1):
print("Thats not the SECRET WORD.")
total_lifes -= 1
continue
# if you input a whole word, this will decrease the lives
# as no multiletter-input can be in your set of characters
if(guess in characters_needed):
print("You guessed it right {} is in SECRET WORD".format(guess))
characters_guessed.add(guess)
change_user_output(guess)
else:
print("There is no such letter in the SECRET WORD, you loose a life")
change_user_output(guess)
total_lifes -= 1
if (characters_needed.issubset(characters_guessed)):
print("You guessed all the characters. The secret word is {}".format(secret_word))
break
if total_lifes == 0:
print("You've lost all lifes, GAME OVER FOR YOU")
print("The SECRET WORD was : %s"%"".join(secret_word))
Output (for a,p,l,e):
#####
Guess any letter : a
You guessed it right A is in SECRET WORD
A ? ? ? ?
#####
Guess any letter : p
You guessed it right P is in SECRET WORD
A P P ? ?
#####
Guess any letter : l
You guessed it right L is in SECRET WORD
A P P L ?
#####
Guess any letter : e
You guessed it right E is in SECRET WORD
A P P L E
You guessed all the characgters. The secret word is APPLE
I also added some safeguarding around allowing whole word or 1 character to be inputted.

Check for repetition in input (Python)

How do i check for a repeating input(letter) for a hangman game?
Example:
word is apple
input is Guess a letter: a
output is Well Done!
then guess next word
input is Guess a letter: a
output should be you already guess that letter.
my codes:
def checkValidGuess():
word = getHiddenWord()
lives = 10
num = ["1","2","3","4","5","6","7","8","9",]
#guessed = ''
while lives != 0 and word:
print("\nYou have", lives,"guesses left")
letter = input("Guess a letter or enter '0' to guess the word: ")
if letter.lower() in word:
print("Well done!", letter, "is in my word!")
lives -= 1
elif len(letter)>1:
print("You can only guess one letter at a time!")
print("Try again!")
elif letter in num:
print("You can only input letter a - z!")
print("Try again!")
#elif letter in guessed:
#print("repeat")
elif letter == "0":
wword = input("What is the word?").lower()
if wword == word:
print("Well done! You got the word correct!")
break
else:
print("Uh oh! That is not the word!")
lives -= 1
#elif letter == "":
#print("Uh oh! the letter you entered is not in my word.")
#print("Try again!")
else:
print("Uh oh! the letter you entered is not in my word.")
print("Try again!")
lives -= 1
Thanks.
You could store the inputs in a list, let's call it temp.
Then you could check to see if the input exists in the list when the user goes to input a new letter.
guess = input()
if guess in temp:
print "You've already guessed {}".format(guess)
else:
#do whatever you want
Here's an easy way. Start by initializing a list:
guesses = []
Then in your loop:
letter = input("Guess a letter or enter '0' to guess the word: ")
if letter in guesses:
print("Already guessed!")
continue
guesses.append(letter)
So you probably want to invert the order of your checks in your program so that you deal with the try again stuff first. Following that change, add another condition that determines if the letter matches those already guessed. This results in something like:
already_guessed = set() # I made this a set to only keep unique values
while lives > 0 and word: # I changed this to test > 0
print(f"\nYou have {lives} guesses left") # I also added an f-string for print formatting
letter = input("Guess a letter or enter '0' to guess the word: ")
if len(letter) > 1:
print("You can only guess one letter at a time!")
print("Try again!")
continue # If you reach this point, start the loop again!
elif letter in already_guessed:
print("You already guessed that!")
print("Try again")
continue
elif letter in num:
print("You can only input letter a - z!")
print("Try again!")
continue
elif letter.lower() in word:
print("Well done!", letter, "is in my word!")
lives -= 1
else:
already_guessed.update(letter)
# It wasn't a bad character, etc. and it wasn't in the word\
# so add the good character not in the word to your already guessed
# and go again!
You would need to add your other conditional branches, but this should get you there. Good luck.

'Strikes{}/10' prints infinitely

Strikes loops infinitely, and I can't fix it. New to Python so forgive any rookie mistakes. Not fully understanding the syntax yet but I've only been at it for three days. I assume it's because of indentation but I'm not sure. Thanks in advance!
import random
words = [
'burger',
'fettucine',
'lasanga',
'steak',
'garlic bread'
'watermelon',
'tea',
'pineapple'
'coffee',
'shrimp penne'
]
while True:
start = input("Press enter to start, or press Q to quit.")
if start.lower() == 'q':
break
secret_word = random.choice(words)
bad_guesses = []
good_guesses = []
while len(bad_guesses) < 10 and len(good_guesses) != len(list(secret_word)):
for letter in secret_word:
if letter in good_guesses:
print(letter, end='')
else:
print('_', end='')
print('')
print('Strikes: {}/10'.format(len(bad_guesses))) # this is what loops
print('')
guess = input("Guess a letter: ").lower()
if len(guess) != 1:
print("You can only guess one letter!")
continue
elif guess in bad_guesses or guess in good_guesses:
print("You have already guessed that letter.")
continue
elif not guess.isalpha():
print("You can only guess letters.") continue
if guess in secret_word:
good_guesses.append(guess) if len(good_guesses) == len(list(secret_word)): print("You win! The word was {}.".format(secret_word))
break
else: bad_guesses.append(guess)
else: print("You didn't get it. The word was{}.".format(secret_word))
Fixed code below.
I found a few issues:
Some indentation and newlines seem to have been lost when you shared the code.
You can't guess spaces, so it's impossible to solve the puzzles that contain spaces ("garlic bread" and "shrimp penne").
There were missing commas after 'garlic bread' and 'pineapple'.
The code that asks for a new guess needs to be inside the inner while loop.
There was an else with no if... I got rid of the else and put that code outside the while loop. Now the game seems to work fine.
Full fixed code here:
import random
words = [
'burger',
'fettucine',
'lasanga',
'steak',
# commented out since you can't guess spaces
# 'garlic bread',
'watermelon',
'tea',
'pineapple',
'coffee',
# commented out since you can't guess spaces
# 'shrimp penne',
]
while True:
start = input("Press enter to start, or press Q to quit.")
if start.lower() == 'q':
break
secret_word = random.choice(words)
bad_guesses = []
good_guesses = []
while len(bad_guesses) < 10 and len(good_guesses) != len(list(secret_word)):
for letter in secret_word:
if letter in good_guesses:
print(letter, end='')
else:
print('_', end='')
print('')
print('Strikes: {}/10'.format(len(bad_guesses))) # this is what loops
print('')
guess = input("Guess a letter: ").lower()
if len(guess) != 1:
print("You can only guess one letter!")
continue
elif guess in bad_guesses or guess in good_guesses:
print("You have already guessed that letter.")
continue
elif not guess.isalpha():
print("You can only guess letters.")
continue
if guess in secret_word:
good_guesses.append(guess)
if len(good_guesses) == len(list(secret_word)):
print("You win! The word was {}.".format(secret_word))
break
else:
bad_guesses.append(guess)
print("You didn't get it. The word was {}.".format(secret_word))

TypeError: 'in <string>' requires string as left operand, not list

I am creating a hangman game for my GCSE Computing Project. I have come across an error that I cannot seem to rectify.
This is all of the code:
import random
#Creates a tuple with words in
WORDS = ("church","smelly","chicks")
#This picks a word randomly
word = random.choice(WORDS)
print("The word is", len(word), "letters long.")
#This is the game
for i in range(1):
letter1 = input ("Guess a letter:")
if letter1 in word:
print("Correct. This letter is in the word")
else:
print("Incorrect. This letter is not in the word.")
for i in range(1):
letter2 = input ("Guess a letter:")
if letter2 in word:
print("Correct. This letter is in the word")
else:
print("Incorrect. This letter is not in the word.")
for i in range(1):
letter3 = input ("Guess a letter:")
if letter3 in word:
print("Correct. This letter is in the word")
else:
print("Incorrect. This letter is not in the word.")
for i in range(1):
letter4 = input ("Guess a letter:")
if letter4 in word:
print("Correct. This letter is in the word")
else:
print("Incorrect. This letter is not in the word.")
for i in range(1):
letter5 = input ("Guess a letter:")
if letter5 in word:
print("Correct. This letter is in the word")
else:
print("Incorrect. This letter is not in the word.")
for i in range(1):
letter6 = input ("Guess a letter:")
if letter6 in word:
print("Correct. This letter is in the word")
else:
print("Incorrect. This letter is not in the word.")
all_letters = [letter1, letter2, letter3, letter4, letter5, letter6]
# Conditions for winning/losing
if all_letters in word:
print("Well done, you got it.")
else:
print("Sorry, You are the loser.")
When I run the program, I get this error
TypeError: 'in <string>' requires string as left operand, not list
I am not sure how to fix this error, can someone please help me?
Also, if you're able to, can you give me some advice on what to improve any section of the whole code.
*This is my first question, forgive me if I've been a bit extensive"
You should do it as follows instead:
if all(i in word for i in all_letters):
print("Well done, you got it.")
else:
print("Sorry, You are the loser.")
This will print 'Well done, you got it.' only if all the letters are in word. It makes use of the all built-in.

Categories