Replace letter in word - python

If the guess is correct it will replace the letter with '-'. in the for loop how can i store the previous result and do a update with the new result?
import random
WORDS = ('linux', 'windows')
correct_word = random.choice(WORDS)
for n in range(5):
guess = input('Enter a letter: ')
letter = ''.join(x if x in guess else '-' for x in correct_word)
if letter in correct_word:
print("So far you have: ", letter)
else:
print("So far you have: ", letter)

Try keeping the letters guessed so far in a variable, like this (I removed the if statement because both branches do the same thing). Also added input validation:
import random
WORDS = ("linux", "windows")
correct_word = random.choice(WORDS)
def get_single_letter_input():
while True:
guess = input("Enter a letter: ")
if len(guess) == 1:
return guess
word_so_far = "".join("-" for letter in correct_word)
for n in range(5):
guess = get_single_letter_input()
word_so_far = "".join(x if x in guess else word_so_far[i]
for i, x in enumerate(correct_word))
print(f"So far you have: {word_so_far}")

You could try doing a regex replacement with re.sub. This answer assumes that you would be OK with using correct_word itself to maintain the state, by being updated with dashes for each matching letter which the user might choose.
import random
WORDS = ('linux', 'windows')
correct_word = random.choice(WORDS)
for n in range(5):
guess = input('Enter a letter: ')
if len(guess) > 1 or len(guess) == 0
print("Please choose a single letter only")
if letter in correct_word:
print("Correct choice")
correct_word = re.sub(guess, '-', correct_word)
else:
print("Letter not present")

Just keep your guessed word in a variable. Also I would recommend not to use fixed range as you do, but get the length of chosen word
def guess():
words = ('linux', 'windows')
correct_word = random.choice(words)
guessed_word = ["-" for letter in correct_word]
for n in range(len(correct_word)):
guess = input('Enter a letter: ')
for i in range(len(correct_word)):
if correct_word[i] == guess:
guessed_word[i] = guess
print("So far you have: ", "".join(x for x in guessed_word))

Here is quick draft for you, I strong believe that you can implement your fully idea:
import random
WORDS = ('linux', 'windows')
correct_word = random.choice(WORDS)
question = list( '-' * len(correct_word))
for n in range(5):
guess = input('Enter a letter: ')
for index, letter in enumerate(correct_word):
if letter is guess:
question[index] = letter
print("So far you have: ", ''.join(question))

Related

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

How to a terminate a while loop?

I have this code that defines a word and I am making guesses of letters that form the actual word. It works perfectly, but I am unable to terminate the loop from taking in user input after I obtain the correct formation of letters. Does any one have an idea in terminating the loop?
word = "EVAPORATE"
guessed_word = "_" * len(word)
word = list(word)
guessed_word = list(guessed_word)
new_list = []
while True:
guess_letter = input("Enter a guess: ")
for index, letter in enumerate(word):
if letter == guess_letter:
guessed_word[index] = letter
print(' '.join(guessed_word))
You can simply change while True to while word != guessed_word, then it will stop after you obtain the correct answer.
This will work
word = "EVAPORATE"
word = word.lower()
word = list(word)
guessed_word = "_" * len(word)
guessed_word = list(guessed_word)
new_list = []
while True:
guess_letter = input("Enter a guess: ")
for index, letter in enumerate(word):
if letter == guess_letter:
guessed_word[index] = letter
print(' '.join(guessed_word))
if '_' not in guessed_word:
print('Congratulation!')
break
you should get to know about flow control statements being break, continue and pass. Look at break for this particular question
You can use break.
For example...
n = 5
while n > 0:
n -= 1
if n == 2:
break
print(n)
print('Loop ended.')

Implementing a game of guessing words in Python

So I am stuck with the part of checking if the letter is present in the word or not. The game needs to let a person guess a letter in the word, and tell if this letter is present in word or not(5 attempts only)
import random
i=0
WORDS= ("notebook","pc", "footprint")
word = random.choice(WORDS)
print(len(word))
while i<5:
inp = input("What's your guess for a letter in the word?\n")
for j in range(0,len(word)):
if inp == word[j]:
print("Yes, we have this letter.")
else:
print("No, we don't have this letter.")
i=i+1
The expected output would be one sentence, either confirming that the letter is present in word, or disproving. However, the actual output is that is prints one sentence per each of letters in the given word, like this:
What's your guess for a letter in the word?
p
Yes, we have this letter.
No, we don't have this letter.
Instead of checking against each letter of the word (and thereby printing it each time), just check whether the letter is in the word:
while i<5:
inp = input("What's your guess for a letter in the word?\n")
if inp in word:
print("Yes, we have this letter.")
You can try regular expression:
import random
import re
i=0
WORDS= ("notebook","pc", "footprint")
word = random.choice(WORDS)
print(len(word))
while i<5:
inp = input("What's your guess for a letter in the word?\n")
res = re.findall(inp, word)
length = len(res)
if length == 0:
print("Your guess is wrong :( ")
else:
print(f"You guess is right :) ")
i +=1
here the output of regular expression is a list so you can do whatever you want with it, e.g. hangman game or ...

Hangman Game - Duplicate characters issue in lists

I've been making a hangman game and ran into a problem with the lists. If the user input matches any of the characters in the list, the letter's place in said list is found and then added to that position in a blank list. However, words such as "television" that contain duplicate characters don't work. Instead, it will print "tel_vis_on". Sorry if this is a vague post, I don't know the terminology.
def guess():
letter = input ("Please enter a letter:")
if letter in word:
print ("Correct!")
letterPlace = word.index(letter)
answer[letterPlace] = letter
print (*answer)
else:
print ("Wrong!")
if answer == word :
print ("You guessed it! Well Done!")
#end here
else:
guess()
from random import choice
objects = ["computer","television"]
word = choice(objects)
word = (list(word))
wordcount = len(word)
answer = ["_"]*wordcount
print (*answer)
guess()
In that part:
if letter in word:
print ("Correct!")
letterPlace = word.index(letter)
answer[letterPlace] = letter
word.index(letter) will return the index of the first occurrence of the letter.
So you'll replace only the first underscore by the letter. Do that instead:
if letter in word:
print ("Correct!")
for letterPlace in (idx for idx,l in enumerate(word) if l==letter):
answer[letterPlace] = letter
the code loops and if it finds the letter, the generator expression yields the index, to replace the underscore.
you can try this if you want. pretty easy to understand if you don't want anything too complicated:
def findOccurences(s, ch):
return [i for i, letter in enumerate(s) if letter == ch]
def guess():
letter = input ("Please enter a letter:")
if letter in word:
print ("Correct!")
letterPlace = findOccurences(word,letter)
for i in letterPlace:
answer[i] = letter
print (*answer)
else:
print ("Wrong!")
if answer == word :
print ("You guessed it! Well Done!")
#end here
else:
guess()
from random import choice
objects = ["computer","television"]
word = choice(objects)
word = (list(word))
wordcount = len(word)
answer = ["_"]*wordcount
print (*answer)
guess()
Nice game by the way.
The issue here is that you are replacing only the first occurrence of the letter. In order to replace all occurances, use the re function like this:
def guess():
letter = input ("Please enter a letter:")
if letter in word:
print ("Correct!")
letterPlace = [m.start() for m in re.finditer(letter, word)]
for index in letterPlace:
answer[index] = letter

Python: Revealing a word for Hangman (Strings, replace, index, and strip)

lets say I have the word: "Pizza"
sAnswer = "Pizza"
sReveal = len(sAnswer)* "_ "
Above I've built a string that'd display "_ _ _ _ _ "
Like any other Hangman game it would contain underscores my problem is: How do I strip the sReveal of spaces, find the index of the letter guessed (example: 'z') and then replace the underscores with z's where necessary and then rebuild the spaces in between, therefore it would become: "_ _ z z _ "
I've tried something like this to no avail:
if sLetterGuessed in list(sAnswer):
for character in list(sAnswer):
index = sAnswer.find(sLetterGuessed)
sReveal = sReveal.replace(" ", "")
list(sReveal)[index] = "z"
print sReveal
for char in sReveal:
sReveal = sReveal.strip(" ")
sReveal = sReveal.replace("_", char)
print sReveal
print HangingMan[iErrors]
## The code is just consideration of the route I'm taking with this; the horrible route.
An easy way to update sReveal is use a list comp and str.join:
sAnswer = "Pizza"
sReveal = len(sAnswer)* "_ "
letter_guessed = "z"
# if letter_guessed == current letter in word, add that letter else add a _
sReveal = " ".join([x if x==letter_guessed else "_" for x in sAnswer ])
print(sReveal)
_ _ z z _
An old hangman game I had to do for a course might be useful:
def hangman(secret_word):
from string import ascii_lowercase
print ("Welcome to Hangman!")
print ("I am thinking of a word that is {} letters long\n-----------".format(len(secret_word)))
guesses = 8
letters_guessed = []
missed_l = ''
correct_l = ''
secret_word = secret_word.lower()
while True:
# if all the letters in secret_word are in correct_l , the user has won
if all(x in correct_l for x in secret_word):
print ("Congratulations, you won!")
break
# if len missed letters is 8, user has used up all guesses so break/end teh game
elif len(missed_l) == 8:
print ("Sorry, you ran out of guesses. The word was {}.".format(secret_word))
break
print ("You have {} guesses left".format(guesses))
print ("Available Letters: {}".format(" ".join([x for x in ascii_lowercase if x not in letters_guessed])))
guess = raw_input("Please guess a letter: ").lower()
# if guess in letters_guessed user has already guessed that letter
if guess in letters_guessed:
print ("Sorry You've already guessed that letter: {}\n-----------".format(guess))
# else if it is in the word, add guess to correct_l and to letters guessed
elif guess in secret_word:
letters_guessed.append(guess)
correct_l += guess
print("Good guess: {}\n-----------".format(" ".join([x if x in letters_guessed else "_" for x in secret_word])))
# if users guess is not in the word, minus a life/guess
elif guess not in secret_word:
letters_guessed.append(guess)
guesses -= 1
print (" That letter is not in my word: {}\n-----------".format(" ".join([x if x in letters_guessed else "_" for x in secret_word])))
missed_l += guess
You're converting sReveal to a list, but you're not saving the list, so it has no effect after all.
Try this:
aReveal = list(sReveal)
index = sAnswer.find(sLetterGuessed)
while index >= 0:
aReveal[index] = sLetterGuessed
index = sAnswer.find(sLetterGuessed, index + 1)
sReveal = ''.join(aReveal)
print sReveal

Categories