I'm working on a Python version of hangman that works off of a .txt file wordlist. For some reason, in playthroughs after the initial playthrough, the script won't show certain letters. Everything else works the way I want it to, more or less.
My code:
import random
wordlist = open("wordlist.txt").read().split()
word = random.choice(wordlist)
strikes = 0
hidden_letters = []
alphabet = "abcdefghijklmnopqrstuvwxyz"
guesses = []
def new_word():
global word
global guesses
word = random.choice(wordlist)
for letter in set(word):
if letter in alphabet:
hidden_letters.append(letter)
guesses = []
def current_progress():
for letter in word:
if letter in hidden_letters:
print '_',
elif letter == ' ':
print ' ',
else:
print letter,
print "\n"
def play_again():
global strikes
print "Would you like to play again?"
answer = raw_input("y/n: ")
if answer == "y":
strikes = 0
main()
elif answer == "n": exit(0)
else:
print "That's not a valid answer."
play_again()
def letter_in_word(x):
global strikes
global hidden_letters
if x in word:
hidden_letters.remove(x)
print "That letter is in the word."
current_progress()
if hidden_letters == []:
print "You win!"
play_again()
else:
print "You have %d strike(s)." % strikes
elif not x in word:
print "That letter is not in the word."
current_progress()
strikes = strikes + 1
print "You have %d strike(s)." % strikes
def main():
new_word()
current_progress()
global strikes
while strikes < 6 and not hidden_letters == []:
print "Guess a letter. \n Letters that have been already guessed are:", guesses
guess = raw_input("> ")
if guess in alphabet and len(guess) == 1:
if not guess in guesses:
guesses.append(guess)
letter_in_word(guess)
else:
print "You've already guessed that letter. Pick another."
current_progress()
print "You have %d strikes." % strikes
else:
print "Sorry, that's not a valid guess."
current_progress()
print "You have %d strikes." % strikes
if strikes == 6:
print "Oop! You lose."
print "The answer was:", word
play_again()
print "Welcome to Hangman!"
print "Six strikes and you lose."
print "----------"
main()
Your problem: when the player guesses a letter that exists in the current word and in a previous word, but was not guessed in the previous word (the player lost that game), the letter is still in the hidden_letters list because remove(x) only removes the first instance of that letter. In other words, your list contains two of the same letter during some executions, which violates an implied requirement of your code. You can fix this by adding hidden_letters = [] in your new_word() function before you add the new word's letters.
From the Python tutorial (emphasis mine):
list.remove(x)
Remove the first item from the list whose value is x. It is an error
if there is no such item.
Or, I think you could add the statement
del hidden_letters[:]
on the beggining of new_word(). It would clear the hidden_letters list.
Related
I've been trying to make a check for if the input (guesses) belongs to the alphabet and if it's a single character for my simple hangman game, but when I try to run the program it just ignores the entire if sentence. It's been working everywhere else and I just can't find the source of the problem.
Here is my code:
def eng():
letter_list = []
global word
global letter
g = 0
lives = 10
while True:
word = input("Insert The Word: ")
if not word.isalpha():
print("Only letters of the English alphabet are allowed")
else:
print(letter)
break
cls = lambda: print('\n' * 256)
cls()
ready_letters = list(set(word.lower()))
while True:
q = len(ready_letters)
print(q)
while True:
letter = input("Your guess: ")
if not letter.isalpha() and len(letter) != 1:
print("You can make a guess with only one letter of the English alphabet")
else:
break
print(letter_list)
if letter in ready_letters and letter not in letter_list:
letter_list += letter
print("Nice")
g += 1
if g == q:
print(f"The word was: {word}")
print("GG, 🎉🎊")
print("\n")
return
print(f"{g}/{q} letters guessed correctly!")
elif letter in letter_list:
print("You already wrote this letter, try again")
else:
letter_list += letter
print("Oh noie")
lives -= 1
print(f"You have {lives} lives left")
if lives == 0:
print("GG, 웃💀")
return
(read comment)
General tips not related to the issue would also be appreciated.
Thanks for your time!
Simple mistake, instead of using and you should be using or. You want to print our your error message if they type a non-alpha character OR they type more than one letter.
For the most part it seems to be working, but not how I'm trying to get it to work. When I run it I am allowed unlimited tries to guess every single letter in the word until I spell out the word.
But that's not what I am going for, I'm trying to give the users 5 guesses with single letters if the letter is in the word then it will tell them "Yes", there is a(n) (users guess) in my word, but if the letter is not in my word then it will tell them "No", there is not a(n) (users guess) in my word.
After 5 attempt's at guessing different letters I want them to have to guess the full word but I can't figure out how.
This is what I have now:
import random
def get_word():
words = ['cat', 'dog', 'man', 'fox', 'jar']
return random.choice(words).upper()
def check(word,guesses,guess):
status = ''
matches = 0
for letter in word:
if letter in guesses:
status += letter
else:
status += '*'
if letter == guess:
matches += 1
count = 0
limit = 5
if matches > 1:
print ('Yes! there is a(n)',guess,' in my word.')
guesses += guess
elif matches ==1:
print ('Yes! there is a(n)',guess,' in my word.')
guesses += guess
while count > limit:
input('What do you think my word is')
else:
print('No, there is not a(n)',guess,' in my word.')
guesses += guess
while count > limit:
input('What do you think my word is')
return status
def main():
word = get_word()
guesses = ""
guessed = False
print ('I am thinking of a 3 letter word with no repeating letters. You get five guesses of the letters in my word and then you have to guess the word.')
while not guessed:
text = 'Guess a letter in my word:'
guess = input(text)
guess = guess.upper()
count = 0
limit = 5
if guess in guesses:
print ('You already guessed "' + guess + '"')
elif len(guess) == len(word):
guesses += guess
if guess == word:
guessed = True
else:
print('No, there is not a(n) "' + guess + '"')
elif len(guess) == 1:
guesses += guess
result = check(word,guesses,guess)
if result == word:
guessed = True
else:
print (result)
else:
print ('Invalid entry.')
print ('Yes! you correctly guessed')
main()
For starters while not guessed: will continue until guessed is true -> the word was guessed. Next if you want there to be 5 guesses then an answer guess you want to do for i in range(0, 5): then run your guess logic replacing
if result == word:
guessed = True
with
if result == word:
guessed = true
break
to break out of the loop on a correct guess. Then to allow a guess afterwards, outside of the loop, check if already guessed and allow a guess if not.
Also as a side note you should check that they enter one character with something like
guess = input(text)
while len(guess) != 1:
guess = input(text)
I tried to mostly keep your original code and trail of thought. The main changes I made was getting rid of the check-function as I felt it didn't do anything too useful. I also changed the guessed-variable into a list, and utilized it's properties for your evaluations.
import random
def get_word():
words = ['cat', 'dog', 'man', 'fox', 'jar']
return random.choice(words).upper()
def main():
word = get_word()
guesses = []
guessed = False
print('I am thinking of a 3 letter word with no repeating letters.'
' You get five guesses of the letters in my word and then you have'
' to guess the word.\n')
while not guessed and len(guesses)<5:
text = 'Guess a letter in my word:\n'
guess = input(text)
guess = guess.upper()
if guess in guesses:
print ('You already guessed "', guess, '"\n')
elif len(guess) > 1:
guesses.append(guess)
if guess == word:
guessed = True
else:
print('No, ', guess, 'is not the word!\n')
elif len(guess) == 1:
guesses.append(guess)
if guess in word:
print('Yes there is a(n) ', guess, 'in the word!\n')
else:
print('No, there is not a(n)', guess, 'in the word!\n')
else:
print ('Invalid entry.\n')
if guessed:
print ('You correctly guessed the word!\n')
else:
correct_guesses = [guess for guess in guesses if guess in word]
print('Last chance, what is the full word? (HINT: You have'
'correctly guessed ', str(correct_guesses), ')"')
fword = input()
if fword.upper() == word:
print('You correctly guessed the word!\n')
else: print('Tough luck! You are out of chances! The correct'
'word was ', word, '\n')
main()
playing = True
while playing:
print('Would you like to play again?')
answ = input()
if answ.upper() == 'YES':
main()
else:
print('Thank you for playing.')
playing = False
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)
My hangman program is fully functioning except there is one problem, let's say the word is mathematics, I guess m, a, t, h, e - but once I guess the other m, it says I guessed it (as opposed to saying "You already guessed this letter") but it doesn't replace the _.
My Code:
def start():
import random
words = ["barbershop", "cuddle", "furious", "demolition", "centaur", "forest", "pineapple", "mathematics", "turkish"]
word = random.choice(words);
hiddenword = len(word) * "-"
used_letters = []
lives = 6
print "Welcome to Hangman! You have 6 guesses, good luck!"
while True:
print word
print "".join(hiddenword)
guess = raw_input("> ")
hiddenword = list(hiddenword)
if len(guess) > 1:
print "Error: 1 Letter Maximum"
elif len(guess) < 1:
guess = raw_input("> ")
else:
if guess.isdigit() == True:
print "Error: Hangman only accepts letters."
else:
if guess in used_letters and word.count(guess) == 1:
print "You already guessed that letter"
else:
if guess.lower() in word:
print "You got the letter " + "'" + guess + "'" + "!"
hiddenword[word.index(guess)] = guess
used_letters.append(guess)
else:
lives -= 1
print "-1 Guesses"
print "Guesses:", lives
used_letters.append(guess)
if lives == 0:
print "GAME OVER: You're out of guesses, try again!"
break
if hiddenword == word:
print "Cangratulations, you got the word!"
break
start()
P.S. - I know I have a lot of excess code e.g. if statements, please do not comment on that.
The problem appears to be with the line:
hiddenword[word.index(guess)] = guess
The string method .index(x) returns the index of the first incidence of x. So this line will persistently fill in the first "m" in mathematics.
Assuming you want the game to reveal all instances of a letter when it is guessed (e.g., show both m's in "mathematics" when you guess "m"), you can substitute this:
for i, x in enumerate(word):
if word[i] == guess:
hiddenword[i] = guess
for your line:
hiddenword[word.index(guess)] = guess
Also, to get the "Congratulations!" message to appear, you will need to change if hiddenword == word to if ''.join(hiddenword) == word, since hiddenword is a list at this point.
Removing multiple occurences of a character in a string in python is easily achieved using:
your_string.replace("m", "");
http://www.tutorialspoint.com/python/string_replace.htm
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")