I was working on this assignment for the EdX MIT Python course and decided I wanted the output to display differently. Based on my code, I thought that the task program would end when guesses = 0. However, I'm either getting "IndexError: list assignment index out of range" or the program ends at guess 2. This appears to depend on the length of the secretWord. Can anyone point me in the right direction?
def hangman(secretWord):
'''
secretWord: string, the secret word to guess.
Starts up an interactive game of Hangman.
* At the start of the game, let the user know how many
letters the secretWord contains.
* Ask the user to supply one guess (i.e. letter) per round.
* The user should receive feedback immediately after each guess
about whether their guess appears in the computers word.
* After each round, you should also display to the user the
partially guessed word so far, as well as letters that the
user has not yet guessed.
Follows the other limitations detailed in the problem write-up.
'''
trackedguess = []
letcount = ()
letterlist = []
guess = ''
for i in range(0, (len(secretWord)-1)):
trackedguess.append('_')
letcount = len(secretWord)
guessesleft = 8
for i in range(0, 7):
if ''.join(trackedguess) == secretWord:
print('You win!')
break
if guessesleft < 1:
print('You have 0 guesses remaining.')
break
print(trackedguess)
print("You have ", guessesleft, " guesses remaining.")
guess = input('Please guess a letter and press return: ')
if guess in letterlist:
print("You've already guessed that. Try again.")
else:
guessesleft -= 1
letterlist.append(guess)
for i in range(0, len(secretWord)):
if secretWord[i] in letterlist:
coordinate = i
trackedguess[coordinate] = secretWord[i]
hangman(chooseWord(wordlist))
A few things stick out to me:
range uses an exclusive end. That means range(0, (len(secretWord)-1) will iterate one time less than the length of secretWord. You want the lengths to match. More straightforward, less error-prone approaches would be just: trackedGuess = ['_'] * len(secretWord) or trackedGuess = list('_' * len(secretWord)).
You should verify your assumptions. For example, the above case could have been caught easily if you did assert(len(trackedGuess) == len(secretWord)).
for i in range(0, 7) suffers from the same problem as your earlier usage of range(). If you want to iterate 8 (guessesleft) times, then you should use range(0, 8). However, you're also decrementing guessesleft inside the loop and exiting when it reaches 0. Do one or the other, but not both. As your code currently is, if someone enters a guess that they've already made, it will count one iteration against them (which I'm not sure is what you want).
It's a very good attempt, but there are some things that are wrong. I'm going to try to walk through them one by one.
Instead of a for loop, I'd suggest using a while guessesleft>0. In the current implementation the for loop will run for 8 times regardless of whether or not there are any guesses left (for example, try providing the same letter as a guess every time). With the while, however, you gain much more control over the loop.
The trackedguess generation is flawed. It will always miss the last letter of the secretword (this is also the reason you were getting the IndexError) Try for i in range(len(secretWord)) instead. You'll also find it much more concise and readable.
I also took the liberty of moving the win or lose condition down in the loop. Previously, if you won on the last guess, you'd still lose (because the win check condition happened before the input and after that the loop ended); also, the guess wasn't printed if you won (because the loop would break before the print statement).
Revised code below:
def hangman(secretWord):
'''
secretWord: string, the secret word to guess.
Starts up an interactive game of Hangman.
* At the start of the game, let the user know how many
letters the secretWord contains.
* Ask the user to supply one guess (i.e. letter) per round.
* The user should receive feedback immediately after each guess
about whether their guess appears in the computers word.
* After each round, you should also display to the user the
partially guessed word so far, as well as letters that the
user has not yet guessed.
Follows the other limitations detailed in the problem write-up.
'''
trackedguess = []
letterlist = []
for i in range(len(secretWord)):
trackedguess.append('_')
guessesleft = 8
while guessesleft > 0:
print(trackedguess)
print("You have ", guessesleft, " guesses remaining.")
guess = input('Please guess a letter and press return: ')
if guess in letterlist:
print("You've already guessed that. Try again.")
else:
guessesleft -= 1
letterlist.append(guess)
for i in range(0, len(secretWord)):
if secretWord[i] in letterlist:
coordinate = i
trackedguess[coordinate] = secretWord[i]
if ''.join(trackedguess) == secretWord:
print(trackedguess)
print('You win!')
break
if guessesleft < 1:
print('You have 0 guesses remaining.')
break
hangman('test')
Hope that helps.
Related
I'm writing a word guessing game like, what I'm expecting is that results appear in uppercase when is on the right spot. Until now, I write the program and it completely works but, let me show you... This is how it goes:
print("Welcome to the word guessing game!")
print(" ")
secret_word = "heaven"
guess_count = 0
display = '_'*len(secret_word)
(len(secret_word)-1)
word = ["_"] * len(secret_word)
while True:
guess = input("What is your guess? ")
for i in range(len(secret_word)):
if guess == secret_word[i]:
word[i] = guess
if guess == secret_word:
print("")
print("You guessed it!")
break
else:
print("".join(word))
guess_count = guess_count+1
print(f"It took you {guess_count} guesses")
So, I'm not sure where to put the uppercase function.
Since the letters are not present at all in the secret word, it shows an "_".
The letters that are present in the secret word, but in a different spot should be shown as lowercase.
The Letters that are present in the secret word at that exact spot, shown in uppercase.
I tried to find the answer on YT and other sites without success. I just want to understand which functions using (.uppercase) I can use to make it.
Hope you can help me, guys. Thanks in advance!
I do not understand. In your code, it seems as though the guess is a single character, but you do not ask for the spot which is needed to determine if it must be uppercase or lowercase. I tried to answer your question based on wordle, so I guessed the player would have to enter a word.
You'd need something like:
for i in range(len(secret_word)):
if guess[i] = secret_word[i]:
word[i] = guess[i].upper()
elif guess[i] in secret_word:
word[i] = guess[i].lower
I am trying to design a hungman game using simple while loop and if else statement.
Rules of the game:
1.Random word is selected from a list of words
2.User is informed when the word is selected and asked to provide his/ her first guess
3.If the user's guess is correct, the letter is console and inform the user how many letters left
The user will get only 5 lives to play the game.
1.import random
2.import string
3.def hungman():
4.words = ["dog", "monkey", "key", "money", "honey"]
5.used_letters = []
6.word = words[random.randrange(len(words))]
7.lives=5
8.while len(word) > 0 and lives > 0:
9.guess = input("Please guess the letter: ")
10.if 'guess' in word:
11.print(guess, " is a correct guess")
12.used_letters.appened(guess)
13.if used_letters.len == word.len:
14.print("Congratulation, You have guessed the correct letter: ",word)
15.else:
16.remaining_letters = word.len - used_letters.len
17.print("You have", remaining_letters, "left")
18.else:
19.lives = lives - 1
20.if lives == 0:
21.print("Sorry! you don't have more lives to continue the game")
22.print("Correct word is: ", word)
23.break
24.else:
25.print("You have", lives , " left")
26.hungman()
The program should ask for the user input which will store in guess variable. If the letter given by the user is one of the letters of word string then the code prompts that the given input is correct and append the letter in the used_letters list. Else it shows the length of the remaining letters for wrong user input. Additionally, if the user fails to guess the letter correctly he or she will lose 1 life as well.
However, as per my code after the while loop in line number 8 the control goes to line no. 18 although I provided correct letter as user input. Line 10 to 17 totally discarded. I could not find the reason of this nature.
Please help me in this regard.
Thank you
You have a couple of issues in your code.
The one you mentioned is because of quotation marks in line 10. Should be
if guess in word:
in line 12 you have a typo
used_letters.append(guess)
to get the length of a list you should use function len(), e.g.
if len(used_letters) == len(word)
And finally you have an issue with exiting the loop in case of the correct answer. You should use
while len(word) > len(used_letters) and lives > 0:
This question already has an answer here:
Python "if" statement not working
(1 answer)
Closed 4 years ago.
I'm learning Python for fun at the moment, and it went all well until now. I'm trying to extend the "Guess the Word"-Game, for example being able to let the Player choose a Word by himself (when 2 People play, 1 chooses the Word, the other guesses) I bet that my Mistake is obvious to me as soon as you point it out, but I'm gonna ask anyway. Well, here is the Code. I put in the entire Program, even tough only the top part should matter. I just put in the rest because it isn't much and maybe you guys can understand it better then.
print("Do you wish to set the Word yourself, or let the program choose?")
user_input = input("1 for own Input - 0 for Program-Input")
if user_input == 1:
Keyword = input("Type in the Word you want to use!")
else:
Keyword = "castle"
word = list(Keyword)
length = len(word)
right = list ("_" * length)
used_letters = list()
finished = False
while finished == False:
guess = input("Guess a Letter!")
if guess not in Keyword:
print("This letter is not in the word. Sorry...")
for letter in word:
if letter == guess:
index = word.index(guess)
right[index] = guess
word[index] = "_"
if guess in used_letters[0:100]:
print("You already used that letter before!")
else:
used_letters.append(guess)
list.sort(used_letters)
print(right)
print("Used letters:")
print(used_letters)
if list(Keyword) == right:
print("You win!")
finished = True
input('Press ENTER to exit')
My problem is, I wanna add the Function to be able to choose if you want to set a Word yourself, or use the word the Program has, defined as "Keyword". But no matter what I input, it always starts with "Guess a Letter" instead of skipping down to where the program sets the Keyword. Thank you in advance for your answers! :)
There's 2 issues with your code.
You put the entire block of code into the else statement. This means that if the if user_input == 1: block ever executed, you would only ask your user for a word and then the program would end because the else statement would be skipped.
You are using if user_input == 1: as your check and this will never be true because user inputs are always read in as strings. A string 1 will never equal the integer 1. This is why your program always skips to the else statement. You need to do if int(user_input) == 1:
Whenever you collect a user's input using the input function, it is a string, not int. this means you will have to either parse the value into an int or evaluate it with a string.
option 1: parsing to int:
user_input = int(input("1 for own Input - 0 for Program-Input"))
option 2: evaluating with string:
if user_input == "1":
input returns a string not a integer so it can never be equal to 1 instead it will be equal to "1".
Plus the code for the user guessing only runs when the program chooses the word so it needs to be unindented.
As a side note your code currently registered capital letters as being different from lower case, you can fix this by putting a .lower() after each input which will turn all capital letters into lowercase.
print("Do you wish to set the Word yourself, or let the program choose?: ")
user_input = input("1 for own Input - 0 for Program-Input")
if user_input == "1":
Keyword = input("Type in the Word you want to use: ").lower()
else:
Keyword = "castle"
word = list(Keyword)
length = len(word)
right = list ("_" * length)
used_letters = list()
finished = False
while finished == False:
guess = input("Guess a Letter: ").lower()
if guess not in Keyword:
print("This letter is not in the word. Sorry...")
for letter in word:
if letter == guess:
index = word.index(guess)
right[index] = guess
word[index] = "_"
if guess in used_letters[0:100]:
print("You already used that letter before!")
else:
used_letters.append(guess)
list.sort(used_letters)
print(right)
print("Used letters:")
print(used_letters)
if list(Keyword) == right:
print("You win!")
finished = True
input('Press ENTER to exit')
I am making a hang man game. I am trying to cycle through a word and have all the repeats in the letter be appended to my list. For example the word "hello": if the user types in "l" I want all the l's to be added to my list. Right now it is only finding one "l" and if the user types an "l" again it finds the second "l".
I also want the user not to be able to type in another letter if they previously already typed it in.
I have two lists one for right guesses and wrong guesses that store every guess. For example if a user types in "h" in "hello"
"h" is a right guess so it appends to [h] but if they type in "h" again it adds it to the list so it says ["h","h"]. The wrong box works the same way but for words that are wrong. If they type in "z" for the word "hello" it says ["z"] in the wrong box.
Here is my code:
import random
user_input = ""
turns = 5
print("Welcome to Advanced Hang Man!")
print("Use your brain to unscramble the word without seeing its order!")
words = ["hello","goolge","czar","gnat","relationship","victor","patric","gir","foo","cheese"]
# Picks a random word from the list and prints the length of it
random_word = (random.choice(words))
random_word_legnth = (len(random_word))
print("Hint! The length of the word is",random_word_legnth)
hold_random_word = [i for i in random_word]
while turns != 0 and set(right_guess) != set(hold_random_word):
user_input = input("Please type your guess one letter at a time:")
right_guess = []
wrong_guess = []
#Calculating every input
if len(user_input) == 1 and user_input.isalpha():
for i in user_input:
if i in hold_random_word:
right_guess.append(i)
else:
wrong_guess.append(i)
print("Correct guess", ''.join(right_guess))
print("Wrong guess", ''.join(wrong_guess))
I'm not sure what your direct question is, but thinking about a hangman game you want to take the users guess and parse the entire word or phrase they are guessing to see if their guess matches anywhere in the word. I made a hang man game below that will function as expected (minus any error handling) Let me know if any parts confuse you, and i can explain
import random
wordcomp = []
wordguess = []
#this is a word bank for all puzzles, they are randomly chosen
word_bank = ['guess this phrase', 'Lagrange', 'foo', 'another phrase to guess']
# This loop stores each letter in a list, and generates a blank list with correct spaces and blanks for user
rand_word = random.randrange(4)
for i in word_bank[rand_word]:
wordcomp.append(i)
if i == ' ':
wordguess.append(' ')
else:
wordguess.append('__')
print('I am thinking of a word,' , wordguess , ' it has ', len(wordguess), ' characters total, GOOD LUCK \n')
wordlist = wordcomp
count = 0
placeletter = 0
wrongguess = []
guesscount = 0
while wordlist != wordguess:
guess = input('please input a lower case letter within the english alphabet!') ##Check that input is one character, and lower case
guesscount = guesscount + 1
# This for loop scans through to see if the letter that was guessed is in the actual puzzle, and places in the correct spot!!
for t in wordcomp:
if t == guess:
wordguess[placeletter] = guess
placeletter = placeletter + 1
# This check tells them they already guessed that letter... then makes fun of them
if guess in wordguess:
pass
else:
wrongguess.append(guess)
while wrongguess.count(guess) > 1:
wrongguess.remove(guess)
print('you guessed the letter ' , guess , ' already, are you person that suffers short term memory loss...')
print('The word I am thinking of: ' , wordguess)
print('The letters you have already guess are: ', wrongguess)
placeletter = 0
# This tells them they finished the puzzle and the number of guesses it took, if its over 26, it calls them stupid for obvious reasons...
if guesscount >= 26:
print('you are an idiot if it took you more than 26 guesses..... now take a minute, sit silently, and think about why you are idiot if it took over 26 guesses... for hangman... where you guess the letters of the alphabet... YOU GET IT, stupid')
elif guesscount < 26:
print('Congrats you solved the puzzle, w00t!!')
if len(user_input) == 1 and user_input.isalpha():
for i in user_input:
if i in hold_random_word and i not in right_guess:
right_guess.append(i)
elif i not in hold_random_word or i not in wrong_guess:
wrong_guess.append(i)
elif i in hold_random_word:
# here user types something that is already typed and is a right_guess
pass
else:
# Types something wrong, that was already typed
pass
print("Correct guess", ''.join(right_guess))
print("Wrong guess", ''.join(wrong_guess))
It is not clear how you are taking inputs, but I think this code can be further optimized. Give it a shot.
Edit 1:
import random
user_input = ""
turns = 5
print("Welcome to Advanced Hang Man!")
print("Use your brain to unscramble the word without seeing its order!")
words = ["hello","goolge","czar","gnat","relationship","victor","patric","gir","foo","cheese"]
random_word = (random.choice(words))
random_word_legnth = (len(random_word))
print("Hint! The length of the word is",random_word_legnth)
hold_random_word = [i for i in random_word]
# This condition can lead to issues in situations like this - abc and aabbcc [sorry couldn't quickly come up with a good actual example :)]
while turns != 0 and set(right_guess) != set(hold_random_word):
user_input = input("Please type your guess one letter at a time:").strip()
right_guess = []
wrong_guess = []
#Calculating every input
if len(user_input) == 1 and user_input.isalpha():
# user_input is 1 letter so for i in user_input will execute only once
# Use the if structure as defined above
if user_input in hold_random_word:
right_guess.append(i)
else:
# this is missing
turns -= 1
wrong_guess.append(i)
print("Correct guess", ''.join(right_guess))
print("Wrong guess", ''.join(wrong_guess))
elif len(user_input) > 1:
print("Please type only one letter at a time")
elif not user_input.isalpha():
print("Please enter only valid English letters")
else:
# handle this however you want :)
pass
print("Welcome to Hangman! Guess the mystery word with less than 6 mistakes!")
words= ['utopian','fairy','tree','monday','blue']
i=int(input("Please enter a number (0<=number<10) to choose the word in the list: "))
if(words[i]):
print("The length of the word is: " , len(words[i]))
guess=input("Please enter the letter you guess: ")
if(guess in words[i]):
print("The letter is in the word.")
else:
print("The letter is not in the word.")
guesses=1
while guesses<6:
guess=input("Please enter the letter you guess: ")
if(guess in words[i]):
print("The letter is in the word.")
guesses=guesses+1
else:
print("The letter is not in the word.")
guesses=guesses+1
if guesses==6:
print("Failure. The word was:" , words[i])
Just started on this Hangman program in python. I'm doing this on a step by step based on a set of instructions and I'm at the point where I want to write some simple code that checks whether the letter entered is found in the chosen word at all. I'm ignoring the position of the matches, only concerned with counting the number of bad guesses. So far so good it seems, but I've encountered a small but big (if that makes sense) problem. On the sixth bad guess I want the loop to finish and let the user know that they failed and the computer won. I noticed that in my case the loop finishes once the user has entered their sixth guess, whether it be bad or good. So if the word is 'fairy' or whatever, no matter how many correct letters that the user guessed the loop will finish regardless on their 6th go. I want the loop to finish only when the user has entered six bad guesses, so in the example of the word 'fairy' if the user inputs 'f' which would be correct and if the next six guesses are incorrect the "failure" message will be printed as opposed to what I have now.
You have this code:
if(guess in words[i]):
print("The letter is in the word.")
guesses=guesses+1
If you remove that last line, then good guesses won't be counted against you.
Also, I'd be careful about your whitespace. The way you have the question now, only the one guess=input("Please enter the letter you guess: ") line is in the while loop. I'm guessing that is a simple mistake putting the code on StackOverflow, though.
It's a slightly unconventional answer, but here's some edited code with commentary.
print("Welcome to Hangman! Guess the mystery word with less than 6 mistakes!")
words= ['utopian','fairy','tree','monday','blue']
i=int(raw_input("Please enter any number to choose the word in the list: "))%5
#the %6 here means divide the input by six and take the remainder as the answer. I found the instructions a little confusing, and this allows the user to be competely unrestricted in the number that they choose while still giving you a number (0, 1, 2, 3, or 4) that you want. Increasing the number after the % will give you a larger variety of choices.
# if(words[i]):
#this line is unnecessary with the above code, and also would not prevent errors futher along in the code if i was not a number between 0 and 4.
print "Your chosen word is", len(words[i]), "characters long."
# slight wording change here
#guess=input("Please enter the letter you guess: ")
#if(guess in words[i]):
#print("The letter is in the word.")
#else:
#print("The letter is not in the word.")
#guesses=1
# all of this is already accomplished in the loop you wrote below.
incorrect_guesses = 0
# it's always nice to initialize a variable
while incorrect_guesses<6:
guess=str(raw_input("Please enter a letter to guess: "))
# Unless you're using python 3, I would use raw_input rather than input.
if((guess) in words[i]):
print('Correct! The letter "' + guess + '" appears in the word ' + str(words[i].count(str(guess))) + ' times.')
else:
print('Sorry, the letter "' + guess +
'" is not in the word.')
incorrect_guesses=incorrect_guesses+1
# Plusses instead of commas clean up the output a bit, and str(words[i].count(str(guess))) gives you the string form of the number which indicates how many times the guess appears in the word. This is useful in words like "tree".
print("Failure. The word was:" , words[i])
# This is outside the while loop because it gets triggered as soon as incorrect guesses go over 6.
# You can still improve the program by adding a feature which tells the players that they have guessed all of the correct letter and telling them what the word was, and possibly by increasing the word list. You can also tell players when they have already guessed a letter in case they've forgotten.
Hopefully this will be helpful to you in your future python endeavors.