I'm making a hangman game and I need to update the table showing the correct letters. So far the program prints this
Enter a word: hello
[-----] You have 6 guesses left, enter a letter: h
Correct!
[H----] You have 6 guesses left, enter a letter: e
Correct!
[-E---] You have 6 guesses left, enter a letter: l
Correct!
[--LL-] You have 6 guesses left, enter a letter: o
Correct!
[----O] You have 6 guesses left, enter a letter:
What I need the program to do is combine the strings for example [H----] --> [HE---] and so on. How would I do this? As well as end the game when there are no more dashes left.
An example of what I want the program to look like is
[H----]
[HE---]
the program also has to work in a random order for example...
[----O]
[-E--O]
[HE--O]
[HELLO]
This is my code so far
Just loop through the string to be guessed and show either the letter, if that letter was already guessed or '_' in case it hasn't.
In [127]: s = "Apple"
In [128]: already_guessed = ['p', 'e']
In [129]: '[' + ''.join([letter if letter in already_guessed else '_' for letter in s]) + ']'
Out[129]: '[_pp_e]'
Instead of recomputing display_string with "-", use the previous value of display_string. Note: You need to offset the index of display_string because of your brackets.
display_string = "[" + "".join([x if x == letter else display_string[i + 1] for i, x in enumerate(word)]) + "]"
Here's my attempt at an answer, wrote this up before you put up your code, so it may not be what you're looking for, but it works.
def hangman():
answer = raw_input('Enter a word: ') # getting the word
guesses = 6 # number of starting guesses
word = '[' + '-'*len(answer) + ']' # this is the string of interest to be printed
while True:
print word, 'You have %d guesses left' % guesses,
if guesses == 0 or '-' not in word: break
# game finishes if word is guessed, or guesses run out
letter = raw_input(', enter a letter: ') # guess a letter
guesses -= 1 # decrease number of guesses by 1 each time
for index, char in enumerate(answer): # iterate through all letters in answer
if letter == char: # check if guessed letter is in the answer
wordlist = list(word) # representing the word as a list to allow mutation
wordlist[index+1] = letter # mutate the correctly guessed letter
word = ''.join(wordlist) # recombining the list into a string
Related
it's a guess-the-letter game something like hangman. it generates a random word in the length of 4 or 5 it's the user's choice and after that, it displays it like this ^^^^ for 4 letters for example. each time user can guess a letter if it's not right I display a message and says it but if it's right has to display that it is right and display the word something for example like this ^a^^. the letter has to be exactly in the position of the original word. can someone help me with the part where the letter that is guessed is right? How shoul i code that this format ^^^^ be forexample like ^a^^ if the letter guessed is right?
# Choosing the words
if result2 == 4:
word = choice(word4)
else:
word = choice(word5)
guess_list = [] # List of guess letters
sec_word = [] # the list for formatting the random word
for i in range(len(word)):
sec_word.append("*") # To format the random word into ****
while result1 > 0: # Start of the guessing game on the condition that guess left is greater than 0
print("word is:", "".join(sec_word)) # Displaying the word
# Displaying the remaining guess number
print("Guess remaining:", num_guess)
print("Previous guess:", guess) # Showing the previous guest
guess = input("Please guess a letter: ")
guess_list.append(guess) # Add the guess letters to a list
if guess.lower() == "stop" or guess.lower() == "exit":
print("Game Ends!")
break # Letting user end the game at anytime
if guess not in guess_list:
if guess in word: # if the user guess correct letter
print(guess, "is in the word")
else: # if the user guess wrong letter
print("Sorry! letter entered is not present in the word!")
else:
# If a letter is already in list
print("You have already guessed that letter, Try another letter")
result1 -= 1 # After each guess the remaining guess time drops 1 time
and output of the code is supposed to be something like this
Word is: ****
Guesses remaining: 6
Previous Guesses:
Choose a letter to guess: a
‘a’ is NOT in the word! Try again!
Word is: ****
Guesses remaining: 5
Previous Guesses: a
Choose a letter to guess: b
‘b’ is in the word!
Word is: b***
Guesses remaining: 4
Previous Guesses: a
Choose a letter to guess: l
‘l’ is in the word!
Word is: bl**
Guesses remaining: 3
Previous Guesses: a
Choose a letter to guess: a
‘a’ is NOT in the word and has been guessed before.
Guesses remaining: 3
Choose another letter to guess: e
‘e’ is in the word!
Word is: bl*e
Guesses remaining: 2
Previous Guesses: a
Choose a letter to guess: exit
I think this base code will work for this,
Note: You need to find index of all occurrences if character is present more than twice in word ( ex: pool ) here o is occurring twice, so you can loop over the base method to replace both occurrences
original_word = 'avatar'
masked_word = '*' * len(original_word)
i = 4 # this is index of character
if(i == 0):
masked_word = original_word[0] + masked_word[1:]
elif(i == len(original_word)-1):
masked_word = masked_word[:i] + original_word[i]
else:
masked_word = masked_word[:i] + original_word[i] + masked_word[i+1:]
print(masked_word)
I'm trying to program hangman and I run into a problem. In line 48 you see that I'm trying to copy the word that has been guessed so far. But the problem is when the program asks for the next letter. For example, if the user have guessed the letter 'h', it says h____ and the next turn I guess the letter e it says _e___ but I want it to say in this example he___.
word = 'hello'
guessed = False
guess_word = secret_word(word)
a = '____'
while guessed == False:
letter = ask_letter_from_user()
if is_the_letter_in_the_word(word, letter):
locatie_letter_in_woord = location_of_letter_in_word(word, letter)
a = replace(guess_word, locatie_letter_in_woord, letter)
print(a)
Seems like a and guess_word should actually be one variable.
You are passing guess_word to the replace function after every guessed letter, but you are never updating its value. Instead, you're updating a.
Get rid of a. Next time, give all your variables meaningful names, then you might realized that you have two variables for one purpose :-)
Instead of calling replace(guess_word, locatie_letter_in_woord, letter), simply do a = a[:locatie_letter_in_woord] + letter + a[locatie_letter_in_woord+1:]. This will prevent the previous letter from being overwritten.
Output:
wich letter do you want to try?: h
well done! you guessed the letter
youre guessed letters are: h
a: h___
wich letter do you want to try?: e
well done! you guessed the letter
youre guessed letters are: h,e
a: he__
Try this:
you can turn the word into a list and have each letter checked one by one
word = 'hello'
guessed = False
found = []
guess_word = secret_word(word)
while guessed == False:
guess= ask_letter_from_user()
if is_the_letter_in_the_word(word, letter):
print('well done! you guessed the letter')
word_as_list = list(guess_word)
indices = [i for i, letter in enumerate(word) if letter == guess]
for index in indices:
word_as_list[index] = letter
found.append(letter)
print('youre guessed letters are: ' + list_joining(found))
guess_word = "".join(word_as_list)
print(guess_word)
In line 47 in place of:
a = replace(guess_word, locatie_letter_in_woord, letter)
write
a = replace(a, locatie_letter_in_woord, letter)
wich letter do you want to try?: h
well done! you guessed the letter
youre guessed letters are: h
h___
wich letter do you want to try?: e
well done! you guessed the letter
youre guessed letters are: h,e
he__
wich letter do you want to try?:
Still, this program has a problem. When you are calling the function:
def location_of_letter_in_word(word, letter):
return word.find(letter)
Look carefully for the second l in hello; it will return the location of the first l.
I'm trying to build a basic program where the computer selects a word out of a pre-existing list (called "words") and the user must guess the appropriate letters to guess the word. This is what the main function looks like so far:
def game():
word = random.choice(words)
while ' ' or '-' in word:
word = random.choice(words)
if ' ' or '-' not in word:
break
print(f'Hint: The chosen word is {len(word)} letters long')
letters = list(word)
progress = []
while True:
guess = str(input('Guess a letter: '))
if len(guess) > 1:
print('Sorry, guess a single letter: ')
if guess in word:
print(f'The letter {guess} is in the word')
for i, j in enumerate(letters):
if progress.count(guess) >= letters.count(guess):
break
elif j == guess:
progress.insert(i, j)
print('Current progress: ' + '-'.join(progress))
if len(progress) == len(word):
if letters[:] == progress[:]:
print('Congrats! You found the word: ' + str(word))
break
elif guess not in word:
print(f'The letter {guess} is not in the word: Try Again')
continue
My issue is with the for loop where I use enumerate(y) and the respective "elif j == guess" condition. I noticed that when running the function, the code works if the letters that are repeated are successive (ex: in the word "chilly", if I type in "l", the function correctly displays the two l's and the game works as intended). However, if the letters are repeated separately (ex: the word "cologne"), the function doesn't insert the "l" between the two o's, and keeps the two o's together regardless, thus preventing the proper word from ever being guessed. Is there a different method I could use to fix this problem?
You should remember the letters already guessed and simplyfiy the printing to any letter that you remember and use - for any other letter in the word.
Your errror stems from your list and counting method to remember which letters to print or not.
I fixed your incorrect if-condition (see How to test multiple variables against a value? for more on that).
import random
# supply list of words to function to avoid globals
def game(words):
word = random.choice(words)
# fixed your check ... not sure why you do that
while ' ' in word or '-' in word:
word = random.choice(words)
# no break needed, will break if no space/- in
print(f'Hint: The chosen word is {len(word)} letters long')
# remember which letters where guessed already
guesses = set()
while True:
guess = input('Guess a letter: ') # no str needed it is already a str
if len(guess) > 1:
print('Sorry, guess a single letter: ')
continue # back to while loop
# add to guessed letters
guesses.add(guess)
# print message
if guess in word:
print(f'The letter {guess} is in the word')
else:
print(f'The letter {guess} is not in the word: Try Again')
continue # back to while loop
print('Current progress: ', end="")
# assume we have all letters guessed
done = True
for idx, letter in enumerate(word):
if letter in guesses:
# print letter if already guessed
print(letter, end="")
else:
# invalidate assumption and print -
done = False
print("-",end="")
print()
# if assumption not invalidated: done
if done:
print('Congrats! You found the word: ' + str(word))
break
game(["eye", "ear", "egg", "anvil"])
Output:
Hint: The chosen word is 3 letters long
Guess a letter: The letter e is in the word
Current progress: e-e
Guess a letter: The letter r is not in the word: Try Again
Current progress: e-e
Guess a letter: The letter y is in the word
Current progress: eye
Congrats! You found the word: eye
I'm trying to make a hangman game (with only 6 letter words) and I'm trying to write the code for when there is more than 1 of a certain letter (inputted by the user) in the word
tries = 0
n = 0
word = random.choice(word_list)
print(word)
while tries<10:
guess = input("Input a letter: ")
if guess in word:
n = n + 1
print("Correct. You've got,", n,"out of 6 letters.")
if n == 6:
print("You guessed correctly, the word was,", word)
break
elif word.guess(2):
n = n + 2
print("Correct. You've got,", n,"out of 6 letters.")
if n == 6:
print("You guessed correctly, the word was,", word)
break
although the program continues after a double letter is inputted for guess (eg. 's' in 'across') it still doesn't add up the correct number in the 'n' variable
You can use count() for that. Use it to get the number of occurence in the word. This returns 0 if character is not present in word. Like inside your while after input() -
c = word.count(guess)
if c:
n += c
if n == 6:
print("You guessed correctly, the word was,", word)
break
print("Correct. You've got,", n, " out of 6 letters.")
You may want to check whether user input is indeed a character and not a string or ''(empty string). That may confuse the program. Also you are not incrementing tries variable. So, user may get unlimited turns to try
Also, what is word.guess(2) in your code. Is that a typo?
You also need to remove letters that have been guessed already. You can do this using the replace function. Like so:
tries = 0
n = 0
word = random.choice(word_list)
word_updated = word
print(word)
while tries<10:
if n == 6:
print("You guessed correctly, the word was,", word)
break
guess = input("Input a letter: ")
if guess in word:
n += word_updated.count(guess)
word_updated = word_updated.replace(guess, "")
print("Correct. You've got,", n,"out of 6 letters.")
i took the liberty to implement this
import random
from collections import Counter
attempt = 0
tries = 10
correct = 0
character_to_check = 6
word_list = ['hello','hiedaw','rusiaa','canada']
word = list(random.choice(word_list))
print(word)
dic = dict(Counter(word))
while attempt <= tries:
if correct==character_to_check :
print("You guessed correctly, the word was {}".format(word))
correct = 0
break
guess = str(input("enter a letter "))
if len(guess)>1 or len(guess)==0:
print("only 1 letter")
else:
if guess in word:
if dic[guess]>0:
correct += 1
dic[guess]-=1
print("you have guessed correct, you got {} out of {} letter".format(correct, character_to_check))
else:
print("already guessed this character")
attempt+=1
if attempt>tries:
print("attempt exceed allowed limit")
output
['r', 'u', 's', 'i', 'a', 'a']
enter a letter 'r'
you have guessed correct, you got 1 out of 6 letter
enter a letter 'r'
already guessed this character
enter a letter 'u'
you have guessed correct, you got 2 out of 6 letter
enter a letter 's'
you have guessed correct, you got 3 out of 6 letter
enter a letter 'i'
you have guessed correct, you got 4 out of 6 letter
enter a letter 'a'
you have guessed correct, you got 5 out of 6 letter
enter a letter 'a'
you have guessed correct, you got 6 out of 6 letter
You guessed correctly, the word was ['r', 'u', 's', 'i', 'a', 'a']
A funny and unreadable one-liner could do the whole trick:
print(globals().update({"word": __import__("random").choice(['collection','containing','random','words']), "checked" : set(), "f" : (lambda : f.__dict__.update({"letter" : input("Input a letter:\n")}) or ((checked.add(f.letter) or (print("Good guess!") if f.letter in word else print("Bad guess..."))) if f.letter not in checked else print("Already checked...")) or (print("You guessed correctly the word " + word + "!") if all(l in checked for l in word) else (print("Too many attempts... You failed!") if len(checked) > 10 else f())))}) or f() or "Play again later!")
(Do not use in production code probably)
I am using a set to remember both attempted letters and number of attemps, no need for another variable.
I have been looking around to see if I could find something that could help, but nowhere has an answer for what I'm looking for. I have a Hangman game I'm doing for a final project in one of my classes, and all I need is to make it so if a word has a capital letter, you can input a lowercase letter for it. This is the code.
import random
import urllib.request
wp = "http://svnweb.freebsd.org/csrg/share/dict/words?view=co&content-
type=text/plain"
response = urllib.request.urlopen(wp)
long_txt = response.read().decode()
words = long_txt.splitlines()
###########
# Methods #
###########
def Run():
dashes1 = "-" * len(word)
dashes2 = "-" * len(word2)
used_letter = []
dashes = dashes1 + " " + dashes2
#dashes ="-" * len(secretWord)
guessesLeft = 6
while guessesLeft > -1 and not dashes == secretWord:
print(used_letter)
print(dashes)
print (str(guessesLeft))
guess = input("Guess:")
used_letter.append(guess)
if len(guess) != 1:
print ("Your guess must have exactly one character!")
elif guess in secretWord:
print ("That letter is in the secret word!")
dashes = updateDashes(secretWord, dashes, guess)
else:
print ("That letter is not in the secret word!")
guessesLeft -= 1
if guessesLeft < 0:
print ("You lose. The word was: " + str(secretWord))
print(dashes)
else:
print ("Congrats! You win! The word was: " + str(secretWord))
print(dashes)
def updateDashes(secret, cur_dash, rec_guess):
result = ""
for i in range(len(secret)):
if secret[i] == rec_guess:
result = result + rec_guess
else:
result = result + cur_dash[i]
return result
########
# Main #
########
word = random.choice(words)
word2 = random.choice(words)
#print(word)
#print(word2)
secretWord = word + " " + word2 # can comment out the + word2 to do one
word or add more above to create and combine more words will have to adjust
abouve in Run()
splitw = ([secretWord[i:i+1] for i in range(0, len(secretWord), 1)])
print (splitw)
Run()
any bit of help is appreciated. The website I'm using has a bunch of words that are being used for the words randomly generated. Some are capitalized, and I need to figure out how to let the input of a letter, say a capital A, accept a lowercase a and count for it.
you could compare after you converted everything to lowercase.
e.g. you could do
secretWord = word.lower() + " " + word2.lower() # that should make your secret all lowercase
for the input you should do the same:
guess = input("Guess:").lower()
after that it should not matter if it is upper or lower case. it should always match if the letter is the correct one.
hope that helps
Simply check everything in lowercase:
[...]
elif guess.lower() in secretWord.lower():
[...]
and so on.
I would just change this line:
while guessesLeft > -1 and not dashes == secretWord:
to:
while guessesLeft > -1 and not dashes.lower() == secretWord.lower():
This way you are always comparing lower-case representations of the user's input to the lower-case representation of your secretWord. Since this is the main loop for your game, you want to break out of this as soon as the user's guess matches your word regardless of case. Then later in your code, you will still check whether they had any guesses left, and print out their answer and the secret word as before.
No other changes required, I think.
You could just force all comparisons to be made in the same Case, such as lowercase.
Let’s say that your word is "Bacon". and someone enters "o".
That will be a match because quite obviously “o” equals “o” so you can cross that letter off the list of letters left to guess.
But in the case that someone enters “b” then b is NOT equal to “B”.
So why not just force all letters to be compared using the same case?
So your comparison will be like
elif guess.Lower() in secretWord.Lower()
My python is rusty as hell, but the idea here should do what you want to do