How to replace dash with letter - hangman - python

I am trying to make a hangman game for class and I am stuck on how to replace a dash (-) with a correctly guessed letter.
Like if the word was HAPPY and the user guessed the letter p, so it would replace the dash for a letter and look like this: --PP-
Here is my code so far:
def play_game(secret_word):
guesses_left = 8
hangman_dash = len(secret_word) * "-"
while guesses_left > 0:
print("The word now looks like this: " + (hangman_dash))
print("You have " + str(guesses_left) + " guesses left")
letter = input("Type a single letter, then press enter: ")
letter = letter.upper()
if len(letter) != 1:
print("Please enter only one letter.")
elif letter not in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYXZ':
print("Please guess a letter.")
if letter in secret_word:
print("That guess is correct")
else:
print("There are no {}'s in the word".format(letter))
guesses_left = guesses_left - 1

I created a very simple example for this. Essentially if user_input in word then we find the index of the user input and replace it with the hidden letter. The code is not very well written :) but it does the job
def hangman(word):
# Replace word with dashes
hidden_word = "-" * len(word)
print("This is the hidden word " + hidden_word)
# Get user's guess
user_input = input("Guess a letter: ")
# If the user's guess exists in the string
if user_input in word:
# Find all occurences of user's guess in word
occurences = findOccurrences(word, user_input)
# For each occurenc, replace that dash in the string with the correct letter
for index in occurences:
hidden_word = hidden_word[:index] + user_input + hidden_word[index + 1:]
# Return the updated hidden_word
print(hidden_word)
# If the user's guess isn't in the string
else:
user_input = input("Sorry that letter was not found, please try again: ")
# Find all occurences method
def findOccurrences(s, ch):
return [i for i, letter in enumerate(s) if letter == ch]
hangman("hello")nput("Guess a letter: ")
if user_input in word:
occurences = findOccurrences(word, user_input)
for index in occurences:
hidden_word = hidden_word[:index] + user_input + hidden_word[index + 1:]
print(hidden_word)
else:
user_input = input("Sorry that letter was not found, please try again: ")
def findOccurrences(s, ch):
return [i for i, letter in enumerate(s) if letter == ch]
hangman("hello")

Going through the string is not worth programming. Just set the hangman_dash variable to '' every iteration of the loop and make a for loop like the one below to check if each of the letters are correct:
def play_game(secret_word):
guesses_left = 8
while guesses_left > 0:
hangman_dash=''
for i in secret_word:
if i in good_guesses:
hangman_dash+=i
else:
hangman_dash+='-'
print("The word now looks like this: " + (hangman_dash))
...
So if a letter in secret_word has been guessed (or is in the good_guesses string) then whatever that letter is will be added to hangman_dash. Otherwise, '-' will be added.

I've expanded upon the code that redline provided. It checks for alpha characters as well.
def hangman(word):
hidden_word = "-" * len(word)
print("This is the hidden word " + hidden_word)
while True:
user_input = input("Guess a letter: ")
if user_input.isalpha():
if user_input in word:
index = word.find(user_input)
hidden_word = hidden_word[:index] + user_input + hidden_word[index + 1:]
print(hidden_word)
else:
print("Sorry that letter was not found, please try again.")
else:
print("Please use letters in the alphabet.")
hangman("word")
As requested, I've added an example of words that contain two of the same letters. I hope this helps.
def hangman(secret_word):
hangman_dash = len(secret_word) * "-"
while True:
user_input = input("Guess:")
index = 0
for char in secret_word:
if char == user_input:
hangman_dash = hangman_dash[:index] + char + hangman_dash[index + 1:]
print(hangman_dash)
index += 1
hangman("happy")

Related

Putting guessed letters instead of dashes / Hangman / Python

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.

Printing the Guessed Letter

import random
title = ("Guess the Word Title")
print(title.center(80))
Tuple = ()
Tuple = ("Spring", "Summer", "Autumn", "Winter")
TupleItem = random.choice(Tuple)
Item_len = len(TupleItem)
ItemAsteriks = ("*" * Item_len)
print("\n\n\n", ItemAsteriks.center(80), "\n\n\n")
response = "n"
while response == "n":
response = input("Would you like to guess the word (y / n)? ")
if response == "y":
break
letter = input("\nEnter a letter: ")
if letter.upper() in TupleItem.upper():
print("The letter ", letter, "is in the word!\n")
new_message = ""
for i in range(len(TupleItem)):
if TupleItem[i].upper()==letter.upper():
new_message += TupleItem[i]
else:
new_message += ItemAsteriks[i]
ItemAskeriks = new_message
else:
print("The letter ", letter, "is not in the word!\n")
GuessedWord = input("\nGuess the word then: ")
if GuessedWord.upper() == TupleItem.upper():
print("You guessed the right word. Congratz!")
else:
print("You guessed the wrong word. The right word was:", TupleItem)
input("\n\nPress Enter to Exit. ")
This is what i've come up so far. If the word is "Summer" and user guessed letter "U", I want to show/update the asterisks like: *u****., and so on. I tried some print commands under the for loop but i couldnt figure it out.
Well, I think the problem is that it will always just show the most recent letter, but not the ones from before. I would initialise a list of strings, one for each letter in the word, starting with
guessed = ["*"] * len(TupleItem)
Then at each guess, iterate though the real word and replace * entries with the actual guessed letter.
for k, ch in enumerate(TupleItem.upper()):
if ch == letter.upper():
guessed[k] = ch
Then you can simply
print("".join(guessed))

Debugging a "guess the word " game

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()

how to fix this python hangman game?

I have coded this hangman game to test something, and it doesn't work properly.
Here is the code:
import random
from string import ascii_lowercase, ascii_uppercase
secret_words = ["screen", "secret", "game", "hangman"]
def lowerChar(c):
if 'A' <= c <= 'Z':
return ascii_lowercase[ascii_uppercase.index(c)]
else:
return c
def get_guess():
word = random.choice(secret_words)
length = len(word)
limit = 5
count = 0
display = "*" * length
print(display, " Is the word")
while count < 5:
letter = input("Please Enter Your guess letter")
for l in word:
if letter.lower() == lowerChar(l):
print("Right guess!")
index = word.find(l)
display = display[:index] + letter + display[index + 1: ]
print(display)
if not '*' in display:
print("You won!")
break
else:
count += 1
print("You got it incorrect, you have: ", limit - count , " Additional trials")
get_guess()
You are doing too much inside the block for l in word. You have to check, whether the character is contained in the word or not, outside this loop:
import random
secret_words = ["screen", "secret", "game", "hangman"]
def get_guess():
word = random.choice(secret_words)
count = 0
display = "*" * len(word)
print(display, " Is the word")
while count < 5:
letter = input("Please Enter Your guess letter")
if letter.lower() not in word:
count += 1
print("You got it incorrect, you have: ", limit - count , " Additional trials")
else:
print("Right guess!")
new_display = ''
for w, l in zip(word, display):
if letter.lower() == w:
new_display += letter.lower()
else:
new_display += l
display = new_display
print(display)
if not '*' in display:
print("You won!")
break
get_guess()
An alternative solution to Daniel's would be introducing a variable called goodGuess that allows you to check if the person has made a correct guess in the for loop, and then once you have exited the for loop, then checking if the player has made an incorrect guess, see below
import random
from string import ascii_lowercase, ascii_uppercase
secret_words = ["screen", "secret", "game", "hangman"]
def lowerChar(c):
if 'A' <= c <= 'Z':
return ascii_lowercase[ascii_uppercase.index(c)]
else:
return c
def get_guess():
word = random.choice(secret_words)
length = len(word)
limit = 5
count = 0
display = "*" * length
print(display, " Is the word")
while count < 5:
letter = input("Please Enter Your guess letter")
#as we do not yet know if this guess is good we set it to False until we do know
goodGuess = False
for l in word:
if letter.lower() == lowerChar(l):
#as the player has made a correct guess we set goodGuess to True
goodGuess = True
print("Right guess!")
index = word.find(l)
display = display[:index] + letter + display[index + 1: ]
print(display)
if not '*' in display:
print("You won!")
break
#checking if the player has made a correct guess
if not goodGuess:
count += 1
print("You got it incorrect, you have: ", limit - count , " Additional trials")
get_guess()
Hope this helps.

How to reveal letters if correct to what is inputted

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!")

Categories