Number of specific letter in string - python

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.

Related

how to unhide the letters in this game?

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)

Keying either individual letters or an entire word into hangman game

I am currently creating a hangman game for a project. I have managed to code where a user can enter individual letters to guess the secret word. However, I am having trouble adding an additional feature where the user can guess the entire word upfront.
below is my code attempt, may I know what to write to have this new feature in my game?
def game_play():
word = random.choice(WORDS)
# Dashes for each letter in each word
current_guess = "-" * len(word)
# Wrong Guess Counter
wrong_guesses = 0
# Used letters Tracker
used_letters = []
while wrong_guesses < MAX_WRONG and current_guess != word:
print (HANGMAN[wrong_guesses])
print ("You have used the following letters: ", used_letters)
print ("So far, the word is: ", current_guess)
guess = input ("Enter your letter guess:")
guess = guess.upper()
# Check if letter was already used
while guess in used_letters:
print ("You have already guessed that letter", guess)
guess = input ("Enter your letter guess: ")
guess = guess.upper()
# Add new guess letter to list
used_letters.append(guess)
# Check guess
if guess in word:
print ("You have guessed correctly!")
# Update hidden word with mixed letters and dashes
new_current_guess = ""
for letter in range(len(word)):
if guess == word[letter]:
new_current_guess += guess
else:
new_current_guess += current_guess[letter]
current_guess = new_current_guess
else:
print ("Sorry that was incorrect")
# Increase the number of incorrect by 1
wrong_guesses += 1
# End the game
if wrong_guesses == MAX_WRONG:
print (HANGMAN[wrong_guesses])
print ("You have been hanged!")
print ("The correct word is", word)
else:
print ("You have won!!")
game_play()
Rather than prompting the user for a new guess each time, you could overwrite the line where you output their previous guesses so far, so the output may look something like:
Word: _ A N _ _ A N Misses: B C D
This would mean they could just keep typing guess and the line would update. See python overwrite previous line for details on how to overwrite previous line.
The input command will let you enter multiple letters. I don't see anything stopping the user entering the full word there already?
Instead of counting each letter which matches/fails you could maintain a set of correct/failed guesses and check against the number of items in the set. Maybe something like:
import random
WORDS = ['STACK', 'OVERFLOW', 'HELP']
def playgame():
word = random.choice(WORDS)
# valid characters
valid = set((chr(c) for c in range(ord('A'), ord('A') + 26)))
# unique characters in word
unique = set((c for c in word))
hits = set()
misses = set()
allowed_misses = 5
complete = False
while complete == False:
guess = input("Enter your guess: ").upper()
for c in (c for c in guess if c in valid):
if c in unique:
hits.add(c)
else:
misses.add(c)
# break out of for
if len(hits) == len(unique) or len(misses) > allowed_misses:
complete = True
break
if not complete:
# output continuation messages
print(f'Hits: {hits} misses: {misses}')
if len(hits) == len(unique):
# output sucess message
print(f'Success: hits {hits} misses {misses}')
else:
# output fail message
print(f'Fail: hits {hits} misses {misses}')
if __name__ == '__main__':
playgame()
I have included the additional feature to enter the entire word, and also refactored your code. If the user entered the entire word correctly, I'd assign current_guess with the correct word and break the while loop. Please have a look
import random
WORDS = ['apple', 'kiwi', 'banana']
MAX_WRONG = 3
def game_play():
word = random.choice(WORDS).upper()
current_guess = '-' * len(word) #hidden answer
wrong_guesses = 0
used_letters = []
while wrong_guesses < MAX_WRONG and current_guess != word:
print ('\nRemaining tries:', MAX_WRONG - wrong_guesses)
print ('So far, the secret word is: ', current_guess)
print ('You have used the following letters: ', used_letters)
guess = input('Enter your letter guess:').upper()
if guess == word:
current_guess = word
break #exit the while-loop
while guess in used_letters: #check for duplicate input
print ('You have guessed "' + guess + '" already!')
guess = input ('Enter your letter guess: ').upper()
used_letters.append(guess) #append guess to used_letters
if guess in word:
print ('You have guessed correctly!')
new_current_guess = ''
for idx in range(len(word)): #update hidden answer
if guess == word[idx]:
new_current_guess += guess
else:
new_current_guess += current_guess[idx]
current_guess = new_current_guess
else:
print ('Sorry that was incorrect')
wrong_guesses += 1
if wrong_guesses == MAX_WRONG:
print ('\nYou have been hanged!')
print ('The correct word is', word)
elif current_guess == word:
print ('\nYou have won!! The word is:', word)
game_play()
Output:
Remaining tries: 3
So far, the secret word is: ----
You have used the following letters: []
Enter your letter guess: i
You have guessed correctly!
Remaining tries: 3
So far, the secret word is: -I-I
You have used the following letters: ['I']
Enter your letter guess: kiwi
You have won!! The word is: KIWI

Hangman Python, reveal different all indexes containing user's input

Basically if the chosen word is "green" and the user types "e" then I want it to show "__ ee _".
But instead, it shows something like this: __ e __.
How can I fix this? Here is my code:
print("Welcome to hangman game!")
import random
words = ['act', 'air', 'age', 'bag', 'cap', 'map', 'acre', 'card', 'dish', 'wack', 'exam', 'god', 'boards', 'chair', 'count', 'facts', 'house']
word = random.choice(words)
list(word)
letters_guessed = []
wrong_letters = [""]
guesses_left = 8
win_confirm = 0
for i in word:
letters_guessed.append("_")
while guesses_left > 0:
print("\nThe word contains {} letters".format(len(word)))
print("You have {} guesses left".format(guesses_left))
print(*letters_guessed)
user = input("\nEnter a letter --> ")
if user in letters_guessed or user in wrong_letters:
print("You have already entered '{}', enter another letter!".format(user))
guesses_left += 1
if user in word:
letter = word.index(user)
letters_guessed[letter] = user
print(*letters_guessed)
win_confirm += 1
if win_confirm == len(word):
print("You won!")
print("The word was '{}' ".format(word))
break
continue
else:
guesses_left -= 1
wrong_letters.append(user)
if guesses_left <= 0:
print("You don't have any chances left :(")
print("The word was '{}' ".format(word))
If there is any fix please tell me, thanks.
user.index() will get only the first index of the letter.
if user in word:
letter = word.index(user)
letters_guessed[letter] = user
print(*letters_guessed)
Try this code instead:
if guess in ai_word:
for letter, num in zip(ai_word, range(len(ai_word))):
if guess == letter: #If guess is there in actual word then according to the index add it
user_letters[num] = guess
zip() basically gets a element each from two or more iterables and returns them as a tuple. So here zip(ai_word, range(len(ai_word))) gets the letter and also its index so if the letter matches we can easily change the letter with its index.
Edit - As syggested by #Oli int the comments -
You can also use:
if guess in ai_word:
for num, letter in enumerate(ai_word):
if guess == letter: #If guess is there in actual word then according to the index add it
user_letters[num] = guess

Merging strings in python

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

Hangman in python 3.x, finding the position of a letter in secret word

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]))
guesses=0
while guesses<6:
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=guesses+1
if guesses==6:
print("Failure. The word was:" , words[i])
Having problems with finding the position of the guessed letter in mystery word. I want a output that shows the correctly guessed letters in the mystery word.
Ex. Mystery word is blue. User inputs "b". Output is: "The letter is in the word. Letters matched: b___"
There's many ways to write this, how about if you put all guessed letters in the string called guessed and then compute
''.join(c if c in guessed else '_' for c in words[i])
c will be iterating over the characters of words[i], the word to guess.
The c if c in guessed else '_' bit replaces all characters that have not yet been guessed with underscores.
''.join() will glue the characters back together into a string.
I think you're looking for something like this:
word = []
for x in range(len(words[i])):
word.append('_')
if(guess in words[i]):
print("The letter is in the word.")
for index, letter in enumerate(words[i]):
if letter == guess:
word[index] = guess
A full program looking like:
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]))
guesses=0
letters_guessed = []
word = []
for x in range(len(words[i])):
word.append('_')
while guesses < 6:
guess=input("Please enter the letter you guess: ")
if(guess in words[i]):
print("The letter is in the word.")
for index, letter in enumerate(words[i]):
if letter == guess:
word[index] = guess
letters_guessed.append(guess)
else:
print("The letter is not in the word.")
guesses=guesses+1
letters_guessed.append(guess)
print("you have guessed these letters: %s"%(''.join(letters_guessed)))
print("Letters matched so far %s"%''.join(word))
print()
if ''.join(word) == words[i]:
break
if guesses==6:
print("Failure. The word was:" , words[i])
else:
print("YOU'VE WON!! Great Job!")
print("You only made %i wrong guesses"%guesses)
which outputs:
> Welcome to Hangman! Guess the mystery word with less than 6 mistakes!
> Please enter a number (0<=number<10) to choose the word in the list: 2
> The length of the word is: 4
> Please enter the letter you guess: e
> The letter is in the word.
> you have guessed these letters: e
> Letters matched so far __ee
The code above works, but having only 5 items in the list of words to choose you can have an error if you input a number higher than 5, so I put some other words in the list, but I also deleted the lines with the input function where the user is asked to digit the number of the item related to the word to discover.
So:
I imported the random module.
I deleted the input code.
I used the random.sample function to store the word to discover (line 12).
I substituted words[i] with samplecode[0] as label for the word to discover.
I added a space after the underscore in word.append('_ ') to make the number of the letters more evident ( _ _ _ _ _ instead of _____ ).
import random
print("Welcome to Hangman! Guess the word in less than 6 try.")
words= ['utopian','fairy','tree','monday','blue',
'winner','chosen','magician','european',
'basilar','fonsaken','butter','butterfly',
'flipper','seaside','meaning','gorgeous',
'thunder','keyboard','pilgrim','housewife'
]
sampleword = random.sample(words,1)
if(sampleword[0]):
print("The length of the word is: " , len(sampleword[0]))
guesses=0
letters_guessed = []
word = []
for x in range(len(sampleword[0])):
word.append('_ ')
while guesses < 6:
guess=input("Please enter the letter you guess: ")
if(guess in sampleword[0]):
print("The letter is in the word.")
for index, letter in enumerate(sampleword[0]):
if letter == guess:
word[index] = guess
letters_guessed.append(guess)
else:
print("The letter is not in the word.")
guesses=guesses+1
letters_guessed.append(guess)
print("you have guessed these letters: %s"%(''.join(letters_guessed)))
print("Letters matched so far %s"%''.join(word))
print()
if ''.join(word) == sampleword[0]:
break
if guesses==6:
print("Failure. The word was:" , sampleword[0])
else:
print("YOU'VE WON!! Great Job!")
print("You only made %i wrong guesses"%guesses)

Categories