I can't get my code to trigger the winning condition, I don't know what am I missing.
The game uses Python turtle to draw the hangman, but this is the part where the game, actually the function, stops when I lose, but doesn't stop when I win:
def startGame():
word_list = ["cat", "dog", "fly", "hi", "bye", "five", "four"]
word = word_list[random.randint(0, 6)]
allowedGuesses = 5
guessesSoFar = 0
lettersUsedSoFar = ''
guss_word = ['_' for x in word]
name = input("What is your name? ")
print("Hello, " + name, ",it's time to play HangMan!")
print(guss_word)
while guessesSoFar < allowedGuesses:
guess = input("Guess a Letter!:")
if guess in word:
guess == lettersUsedSoFar
guss_word[word.index(guess)] = guess
print(guss_word)
print("Yes!" + guess + " is in the word")
print("Your Guesses So Far:" + lettersUsedSoFar)
else:
lettersUsedSoFar = lettersUsedSoFar + guess + ","
guessesSoFar = guessesSoFar + 1
drawHangman(guessesSoFar)
print(guss_word)
print("Oops!" + guess + " is not in the word")
print("Your Guesses So Far:" + lettersUsedSoFar)
startGame()
One obvious error is this line:
guess == lettersUsedSoFar
which does nothing. (Fortunately.)
You need a test to determine if the user has won. Since guss_word starts out as all underscore characters, the test could be whether it has any underscore left in it:
if '_' not in guss_word:
# Winner! (Now get out of program.)
else:
# Good answer but keep playing
Below is my rework of your program with this fix, style changes and code optimizations:
from random import choice
WORD_LIST = ["cat", "dog", "fly", "hi", "bye", "five", "four"]
ALLOWED_GUESSES = 5
def drawHangman(count):
pass
def startGame():
name = input("What is your name? ")
print("Hello, " + name,", it's time to play HangMan!")
guessesSoFar = 0
letters_used = ''
word = choice(WORD_LIST)
incomplete_word = ['_' for x in word]
print(*incomplete_word)
while guessesSoFar < ALLOWED_GUESSES:
letter = input("Guess a letter: ")
if letter in word:
incomplete_word[word.index(letter)] = letter
print(*incomplete_word)
if '_' not in incomplete_word:
print("You win!")
break
else:
print("Yes!", letter + " is in the word.")
else:
if letter not in letters_used:
letters_used += letter
guessesSoFar += 1
drawHangman(guessesSoFar)
print(*incomplete_word)
print("Oops!", letter + " is not in the word")
print("Your guesses so far:", ','.join(letters_used))
startGame()
Neither this rework, nor your original, clearly define how they handle repeated letters, like the 'e' in 'here'.
Related
i made hangman and am using this code. everything works fine, i just want to replace dashes in the list [lenghtDashes] with the correctly guessed letter in the corresponding place. i could not find any information online or here as well. maybe someone knows.
im open to any improvement suggestions as well.
secWord = input("What is the word for others to guess?: ")
life = 10
#starting information
i = 1
while i < 10:
print(".")
i += 0.01
#dots so players can not see the word
print("you have 10 tries to guess the word")
print("you will have to choose between gessing a letter (l) or a word (w) in start of every turn")
print("however, if you guess the word incorrectly you will lose immediately")
ans = input("are you ready to begin?: ")
while ans != "yes":
ans = input("now? ")
#rules
i = 1
while i < 10:
print(".")
i += 0.01
#dots for taking players to start
lenghtDashes = []
for letter in range(len(secWord)):
lenghtDashes.append("_")
#making dashes list
print("let's begin")
print("the word has " + str(len(secWord)) + " letters.")
appended = "".join(lenghtDashes)
print(appended)
#info for players
usedLetters = []
guessedLetters = []
wordLis = []
while life > 0 and ans != secWord:
print("are you guessing letter or a word?")
guessThing = input("l / w : ")
#for guessing a word
if guessThing == "w":
ans = input("What is the secret word?: ")
if ans == secWord:
print("Congratulations, you have guessed the right word\nYou won!")
else:
print("You guessed the word incorrectly\n The word was " + secWord + " \n You lost!")
exit()
#=================================================================
#for guessing a letter
elif guessThing == "l":
letList = [letter for letter in secWord]
guLett = input("Guess the letter \n(single letter only): ")
usedLetters.append(guLett)
if guLett in letList:
guessedLetters.append(guLett)
letListPlus = [letter for letter, x in enumerate(letList) if x == guLett]
letListPlusPlus = [num + 1 for num in letListPlus]
print("///")
print("///")
print("///")
print("Letters that you have used : " + str(usedLetters))
print("Letter that are correct: " + str(guessedLetters))
print("The position of letter " + str(guLett) + " is " + str(letListPlusPlus))
else:
print("///")
print("///")
print("///")
print("incorrect guess, you have " + str(life - 1) + " guesses remaining")
life = life - 1
print("Letters that you have used are: " + str(usedLetters))
print("Letter that are correct: " + str(guessedLetters))
#=================================================================
Whenever you need your in-progress word to be displayed (like "o_e_f_ow"), call this function:
def wordWithDashes(guessedLetters, letList):
return [letter if letter in guessedLetters else "_" for letter in letList]
It creates a new list from letList with missing letters replaced with "_". You can use str on it if you want a string result.
You don't need to keep track of lenghtDashes. Just compute it from the guessed letters and the actual word whenever you need it, as the code I provided does.
There is one small problem with my code , after I get all the letters correct, I had to enter another letter only it will show that I got it right. What is the problem?
import random
import string
import sys
def split(word):
return list(word)
alphabet = 'abcdefghijklmnopqrstuvwxyz'
list(alphabet)
words = ['hat','pop' ,'cut' , 'soup' , 'you' , 'me' , 'gay' , 'lol' ]
guess_word = []
wrong_letters_storage = []
secret_word = random.choice(words)
word_length = print("the length of the word is " + str(len(secret_word)))
correct_letters = split(secret_word)
def words():
for letter in secret_word:
guess_word.append("-")
return print("the words that you are guessing is " + str(guess_word))
def guessing():
while True:
c = 0
b = 7
while c <= 7:
print("")
hide = ""
print("you have " + str(b) + " guess left")
print("Wrong letters : " + str(wrong_letters_storage))
command = input("guess: ").lower()
if not '-' in guess_word:
print("you win!")
break
elif command == 'quit':
print("thank you for playing my game")
break
else:
if not command in alphabet :
print("pick an alphabet")
elif command in wrong_letters_storage:
print("you have picked this word")
else :
if command in secret_word :
print("right")
c += 1
b -= 1
for x in range(0, len(secret_word)):
if correct_letters[x] == command:
guess_word[x] = command
print(guess_word)
elif not command in secret_word :
print("wrong")
wrong_letters_storage.append(command)
c += 1
b -= 1
else :
print("error")
print("*"*20)
return print("Thank you for playing my game")
words()
guessing()
print("the words that you are guessing is " + secret_word )
Your code has several "problems":
you check if the current solution has no more '-' in it, after you ask for the next character input()
return print("whatever") returns None because the print function prints and returns None
you use variables with single_letter_names that make it hard to know what they are for
you use list's instead of set()'s for lookups (its fine here, but not optimal)
You can fix your problem by moving the test statement before the input() command:
# your code up to here
while True:
c = 0
b = 7
while c <= 7:
if not '-' in guess_word:
print("you win!")
break
print("")
hide = ""
print("you have " + str(b) + " guess left")
print("Wrong letters : " + str(wrong_letters_storage))
command = input("guess: ").lower()
if command == 'quit':
print("thank you for playing my game")
break
else:
# etc.
It would probably be better to do some more refaktoring:
import random
import string
import sys
def join_list(l):
return ''.join(l)
def guessing():
# no need to put all this in global scope
alphabet = frozenset(string.ascii_lowercase) # unchangeable set of allowed letters
words = ['hat', 'pop', 'cut', 'soup', 'you', 'me', 'beautiful', 'lol']
secret = random.choice(words) # your random word
secret_word = list(secret.lower()) # your random word as lowercase list
wrong = set() # set of wrongly guessed characters
right = set() # set of already correctly guessed characters
correct = frozenset(secret_word) # set of letters in your word, not changeable
guess_word = ['-' for k in correct] # your guessed letters in a list
guesses = 7
guessed = 0
print("The length of the word is ", len(secret))
# loop until breaked from (either by guessing correctly or having no more guesses)
while True:
print("")
print(f"you have {guesses-guessed} guess left")
if wrong: # only print if wrong letters guessed
print(f"Wrong letters : {wrong}")
# print whats know currently:
print(f"Guess so far: {join_list(guess_word)}")
command = input("guess: ").strip().lower()
try:
if command != "quit":
command = command[0]
except IndexError:
print("Input one letter")
continue
if command == 'quit':
print("thank you for playing my game")
break
else:
if command not in alphabet:
print("pick an alphabet")
continue
elif command in (wrong | right):
print("you already picked this letter")
continue
else :
guessed += 1
# always lookup in set of lowercase letters
if command in correct:
right.add(command)
for i,letter in enumerate(secret_word):
if command == letter:
# use the correct capitalisation from original word
guess_word[i] = secret[i]
else:
print("wrong")
wrong.add(command)
print("*"*20)
# break conditions for win or loose
if join_list(secret_word) == join_list(guess_word):
print("You won.")
break
elif guessed == guesses:
print(f"You lost. Word was: {join_list(secret_word)}")
break
guessing()
Hi im 2 weeks into my python class at school and i made a simple hangman type game heres the code
secret = "computers"
my_string = ""
guesses = 10
welcome = input("Welcome to hangman, whats your name? ")
print("Hi " + welcome + " lets get started.")
secret = "computers"
my_string = ""
guesses = 10
welcome = input("Welcome to hangman, whats your name? ")
print("Hi " + welcome + " lets get started.")
while guesses >= 0:
guess = input("Guess a letter: ")
if guess in secret:
print("Correct")
my_string = my_string + guess
print(my_string)
elif guess not in secret:
print("incorrect")
guesses = guesses - 1
print("You have " + str(guesses) + " left.")
if my_string == "computer":
print("Congrats you won!")
break
if guesses == -1:
print("You lost.")
break
the problem is that once i type a letter it does not print in the correct order. For example if I type "o" first and then guess the rest in the correct order it will print "ocmputers" if anyone can help i would really appreciate it.
Since you are new I would like to help you with a better version of hangman. The code below is chopped and changed version of your hangman. This is the code:
def choose_word():
word = 'computers'
return {'word':word, 'length':len(word)}
def guess_letter(word_, hidden_word_, no_guesses_, letters_):
print('---------------------------------------')
print('You have', no_guesses_, 'guesses left.')
print('Available letters:', letters_)
guess = input("Please guess a letter:")
guess = guess.lower()
if guess in letters_:
letters_ = letters_.replace(guess, '')
if guess in word_:
progress = list(hidden_word_)
character_position = -1
for character in word_:
character_position += 1
if guess == character:
progress[character_position] = guess
hidden_word_ = ''.join(progress)
print('Good guess =', hidden_word_)
else:
print('Oops! That letter is not in my word:', hidden_word_)
no_guesses_ = no_guesses_ - 1
else:
print('The letter "', guess, '" was already used!')
no_guesses_ = no_guesses_ - 1
if hidden_word_ == word_:
print('Congratulations, you won!')
return True
if no_guesses_ == 0 and hidden_word_ != word_:
print('Game over! Try again!')
return False
return guess_letter(word_, hidden_word_, no_guesses_, letters_)
def hangman():
hangman_word = choose_word()
print('Welcome to the game, Hangman!')
print('I am thinking of a word that is', hangman_word['length'], 'letters long.')
hidden_word = ''.join(['_'] * hangman_word['length'])
no_guesses = 8
letters = 'abcdefghijklmnopqrstuvwxyz'
guess_letter(hangman_word['word'], hidden_word, no_guesses, letters)
hangman()
You build the output sting this way:
my_string = my_string + guess
So you just put the correctly guessed letters one after another in the order they were guessed disregarding thier order in the secrete word.
Your conflicting lines are these ones
if guess in secret:
print("Correct")
my_string = my_string + guess
If you look closely, when you first add a letter, lets say o, my_string is empty, and then you add to it guess variable.
>>> print(my_string)
"o"
and then if you add c
>>> print(my_string)
"oc"
I would recommend having a different method for checking if you have entered a char of the secret word.
I am creating a hangman game , where a user will enter a word in which another user will have to guess.
I have got the word to print with dashes, however when I input a letter which is in the word, I cannot get it to remove the dashes.
#output a game of hangman
letters= ["A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z"]
for i in range(1):
print("Welcome to Hangman")
word_guess = str(input("Please enter a word for user 2 to guess:"))
print("Word to be guessed:"+str(word_guess))
length_of_word=len(word_guess)
display=("-"*length_of_word)
print("Display:"+str(display))
for i in range(1):
print("Welcome to Hangman Player 2")
letter_guess=str(input("Please guess a letter:"))
if letter_guess in word_guess:
print("Yay you have a match")
display=display.rstrip(display)
print(display)
Hangman
Try this code, is not refinished, but it works. Maybe it can give you some ideas. To work, you got to be connected, otherwise put the file with words on the computer.
from urllib.request import urlopen
from random import choice
w0 = urlopen("https://raw.githubusercontent.com/Xethron/Hangman/master/words.txt")
w = [str(x).replace("b'", "").replace("\\n", "") for x in w0]
word = choice(w)
word = word.replace("'", "")
strips = list("_" * len(word))
chosen = []
def guess():
y = input("Guess a letter: ")
if y in chosen:
print("You have choose this letter yet, retry...")
guess()
chosen.append(y)
if y in word:
if "_" not in strips:
print("GREAT, YOU WIN!")
print()
print()
pass
print("Great the letter is in the word")
indexes = [x for x, y2 in enumerate(word) if y == y2]
for ind in indexes:
strips[ind] = y
for ch in strips:
print("[" + ch + "]", end='')
print("You`ve choosen: ", "".join(chosen))
print()
print()
guess()
else:
print("This letter is not in the word, try again")
print("".join(strips))
print("You`ve choosen: ", "".join(chosen))
def start():
for ch in range(len(word)):
guess()
print("Game over " * 5)
print("The word was " + word)
print("\n" * 5)
print("HANGMAN - Giovanni Gianni Gatto")
print("print start() to restart")
print()
start()
I had a hangman lying around which I adapted to your needs. What you need is to have a list with found items [] and when you print the word to display you show only letters which are in the found items else _.
print(' '.join(i if i in found else '_' for i in secretword))
Here is a full example of a game where it asks for one_guess (a function) until the length of found items is equal too the length of the set of the secretword (set removes duplicate letters). Try it:
def print_word():
print(' '.join(i if i in found else '_' for i in secretword))
def valid_input():
while True:
guess = input("Guess a letter: ({})".format(''.join(i for i in alpha)))
if guess in alpha:
alpha.remove(guess)
return guess
else:
print("Not valid input!")
def one_guess():
print_word()
guess = valid_input()
if guess in letters:
print("You found one!\n")
letters.remove(guess)
found.append(guess)
else:
print("You didn't find one!\n")
secretword = "animal"
alpha = list("abcdefghijklmnopqrstuvwxyz")
letters = list(set(secretword))
found = []
while True:
one_guess()
if len(set(secretword)) == len(found):
print("You won!")
I am trying to design a simple hangman game, and am currently having issues with looping this game. I am VERY new to Python, and am aware that there is probably quite a simple issue with this, but would appreciate any help.
Here is the code I currently have for the game:
import random
random_words = ["stationery", "notepad", "pencil", "paper","eraser","highlighter","stapler","sharpener"]
computer_choice = random.choice(random_words)
print("The number of letters in the word I have chosen is " + str(len(computer_choice) + ".")
player_guess = None
guessed_letters = []
word_guessed = []
for letter in computer_choice:
word_guessed.append("-")
joined_word = None
player_guess = str(input("Please pick a letter you think is in the word I have chosen."))
attempts = (len(computer_choice)-1)
for letter in (0, len(computer_choice)):
if attempts != 0 and "-" in word_guessed:
joined_word = "".join(word_guessed)
print(joined_word)
guessed_letters.append(player_guess)
for letter in range(len(computer_choice)):
if player_guess == computer_choice[letter]:
word_guessed[letter] = user_input
if player_guess not in computer_choice:
attempts -= 1
player_guess = str("Please try again. You have " + str(attempts) + " attempts remaining.")
if "-" not in word_guessed:
print("Congratulations! {} was the word").format(computer_choice)
else:
print("Unlucky! The word was " + str(computer_choice) + "!")
Currently, the game does not loop, and simply cuts straight to the 'unlucky, the word was ___'. How do I fix this? What is the issue?
When you post the code, please ident it so it's easier to understand and for python to compile as that's essencial in the interpreter.
You code had some errors with the loop as in do not use a for loop to cycle through a simple repetition, use for to cycle through lists. For simple repetition use while. Also same variable in two nested for loops, get things complicated.
Also no need to cycle through every letter in yet another for loop, in operator will already check if character exists or not in word.
I created another way to find and replace the characters in the word, a little bit more straightforward I guess
import random
random_words = ["stationery", "notepad", "pencil", "paper","eraser","highlighter","stapler","sharpener"]
computer_choice = random.choice(random_words)
print("The number of letters in the word I have chosen is " + str(len(computer_choice)))
win = computer_choice #computer_choice will be destroyed later on
print(computer_choice)
guessed_letters = []
word_guessed = []
for letter in computer_choice:
word_guessed.append("-")
joined_word = None
player_guess = input("Please pick a letter you think is in the word I have chosen.")
attempts = (len(computer_choice)+1)
x = 0
while x < len(computer_choice):
x+=1
if attempts != 0 and "-" in word_guessed:
if player_guess in computer_choice:
y=0
while y < computer_choice.count(player_guess): #will count how many times guessed word is in string
y+=1
pos = computer_choice.find(player_guess) #return index of where the letter is
word_guessed[pos] = player_guess #replaces word_guessed with letter in pos
computer_choice = computer_choice.replace(player_guess,'#',1) #deletes so it won't find it again
player_guess = "/"
if player_guess not in computer_choice:
attempts -= 1
print("Please try again. You have " + str(attempts) + " attempts remaining.")
player_guess = input("Please pick a letter you think is in the word I have chosen.")
joined_word = "".join(word_guessed)
print(joined_word)
else:
break
if "-" not in word_guessed:
print("Congratulations! %s was the word"%win)
else:
print("Unlucky! The word was " + str(win) + "!")