How to hide/reveal letters in python game? - python

I'm new to coding and am currently trying to make a simplified game of Hangman using Python 3. For the most part, I have it down, except for the most important part, how to hide the letters of the random word, and then how to reveal them once guessed. Mainly, I just need a quick answer. Any help would be greatly appreciated. Here's my code so far (sorry if it's long, like I said, I relatively new at this, and thanks again!):
import random
#list of words for game
hangmanWords = ("Halloween","Hockey","Minnesota","Vikings","Twins","Timberwolves","Wild","Playstation","Achievement","Minecraft","Metallica","Portal","Xbox","Guitar")
#randomizes the word chosen for game
index = random.randint(0,len(hangmanWords)-1)
#assigns radomized word to variable
randomWord = hangmanWords[index]
'''
menu function, provides user with choices for game, user chooses via imput
'''
def menu():
print("""
Welcome to Hangman!
Select a difficulty:
1. Easy (9 Misses)
2. Medium (7 Misses)
3. Advanced (5 Misses)
4. Exit Game
""")
selection = int(input("What difficulty do you pick (1-4)?: "))
return selection
'''
the function for easy mode, prints the word chosen by randomizer
asks the player to enter a letter that they guess is in the word
player gets 9 guesses to figure out word, correct guesses don't
count, returns player to main menu when they lose
'''
def easyMode():
wrongGuesses = 0
listOfGuesses = []
print(randomWord)
while(wrongGuesses != 9):
x = input("Enter a letter: ")
if x.lower() in randomWord.lower():
print(x,"is in the word!")
listOfGuesses.append(x)
print("Letters guessed so far: ",listOfGuesses)
print()
else:
print(x,"is not in the word.")
wrongGuesses += 1
print(wrongGuesses, "wrong guesses.")
listOfGuesses.append(x)
print("Letters guessed so far: ",listOfGuesses)
print()
print("You lost the game!")
return x
'''
the function for medium mode, prints the word chosen by randomizer
asks the player to enter a letter that they guess is in the word
player gets 7 guesses to figure out word, correct guesses don't
count, returns player to main menu when they lose
'''
def medium():
wrongGuesses = 0
listOfGuesses = []
print(randomWord)
while(wrongGuesses != 7):
x = input("Enter a letter: ")
if x.lower() in randomWord.lower():
print(x,"is in the word!")
listOfGuesses.append(x)
print("Letters guessed so far: ",listOfGuesses)
print()
else:
print(x,"is not in the word.")
wrongGuesses += 1
print(wrongGuesses, "wrong guesses.")
listOfGuesses.append(x)
print("Letters guessed so far: ",listOfGuesses)
print()
print("You lost the game!")
return x
'''
the function for advanced mode, prints the word chosen by randomizer
asks the player to enter a letter that they guess is in the word
player gets 5 guesses to figure out word, correct guesses don't
count, returns player to main menu when they lose
'''
def advanced():
wrongGuesses = 0
listOfGuesses = []
print(randomWord)
while(wrongGuesses != 5):
x = input("Enter a letter: ")
if x.lower() in randomWord.lower():
print(x,"is in the word!")
listOfGuesses.append(x)
print("Letters guessed so far: ",listOfGuesses)
print()
else:
print(x,"is not in the word.")
wrongGuesses += 1
print(wrongGuesses, "wrong guesses.")
listOfGuesses.append(x)
print("Letters guessed so far: ",listOfGuesses)
print()
print("You lost the game!")
return x
'''
main function, deals with what happens depending on
what the player selected on the menu
'''
def main():
select = menu()
while(select != 4):
if(select == 1):
easyMode()
elif(select == 2):
medium()
elif(select == 3):
advanced()
select = menu()
print("You don't want to play today? :'(")
main()

If you want to try it out yourself, then please don't see the code yet. Like in hangman, we get to see our progress (partially guessed word), you should create another variable that holds such a string. And, with every correct guess, you should update this string accordingly. The string obviously starts out as ##### or ***** according to the length of the word to be guessed.
With several improvements, I present to you, Hangman!
All credits go to you of course!
import random
#list of words for game
hangmanWords = ("Halloween","Hockey","Minnesota","Vikings","Twins","Timberwolves","Wild","Playstation","Achievement","Minecraft","Metallica","Portal","Xbox","Guitar")
#assigns radomized word to variable
randomWord = random.choice(hangmanWords)
'''
menu function, provides user with choices for game, user chooses via imput
'''
def menu():
print("""
Welcome to Hangman!
Select a difficulty:
1. Easy (9 Misses)
2. Medium (7 Misses)
3. Advanced (5 Misses)
4. Exit Game
""")
selection = int(input("What difficulty do you pick (1-4)?: "))
return selection
def game(mode):
'''
the game function, prints the word chosen by randomizer
asks the player to enter a letter that they guess is in the word
player gets guesses according to value passed as per mode,
to figure out the word, correct guesses don't count,
returns player to main menu when they lose
'''
modes = {1:9, 2:7, 3:5} # Matches mode to guesses
guesses = modes[mode]
wrongGuesses = 0
listOfGuesses = []
# print(randomWord) Dont't print the solution!!
# Get a random word which would be guessed by the user
to_guess = random.choice(hangmanWords)
to_guess = to_guess.lower()
# The correctly guessed part of the word that we print after every guess
guessed = "#"*len(to_guess) # e.g. "Hangman" --> "#######"
while(wrongGuesses != guesses):
x = input("Word - %s . Guess a letter: "%guessed).lower()
if x in to_guess:
print(x,"is in the word!")
listOfGuesses.append(x)
# Now replace the '#' in 'guessed' to 'x' as per our word 'to_guess'
new_guessed = ""
for index, char in enumerate(to_guess):
if char == x:
new_guessed += x
else:
new_guessed += guessed[index]
guessed = new_guessed # Change the guessed word according to new guess
# If user has guessed full word correct, then he has won!
if guessed == to_guess:
print("You have guessed the word! You win!")
print("The word was %s"%to_guess)
return True # return true on winning
else:
print("Letters guessed so far:", listOfGuesses, "\n")
else:
print(x,"is not in the word.")
wrongGuesses += 1
print("Wrong guesses:", wrongGuesses)
listOfGuesses.append(x)
print("Letters guessed so far:", listOfGuesses, "\n")
print("You lost the game!")
print("The word was %s"%to_guess)
return False # return false on loosing
'''
main function, deals with what happens depending on
what the player selected on the menu
'''
def main():
select = menu()
while(select != 4):
game(select)
select = menu()
print("You don't want to play today? :'(")
main()
Wherever you see copy-paste or code repetition, it's not Pythonic! Try to avoid repetition, especially in functions. (like your easy, medium & hard functions)

The other answer implements it for you, but I'll walk you through the methodology so you can improve as a programmer.
You're going to want two lists, one that has the full word, and one that has the list you want to display. You can either make a binary list that is the same length as the word, or you can make a "display list", that is full of underscores, until the correct letter is guessed.
The display list method should look something like this and is easier to impliment:
To initialize displaylist:
for _ in range(len(randomword)):
displaylist.append("_")
Then within the if statement:
for i in range(len(randomword)):
if x == randomword[i]:
displaylist[i] = x
And then to print, you would need something like this:
print(''.join(displaylist))
Another improvement you could make is making a separate function that checks your word so that you can most effectively use modular programming. This would cut down on code complexity, redundancy, and make it easier to implement changes.

Related

Hangman Issue: How do I make my loop reset when the letter entered is not present and how do I make the letter appear more than once in the word?

The word_chosen is "apple". However, when I enter the letter p, it only appears once in the word. I would also like to make my loop reset when the letter entered is not correct.
def guesses():
guess = 0
hangman_word = "_____"
while guess < 5:
guess_player = input("What is your letter? ")
for i in range(len(word_chosen)):
if guess_player == word_chosen[i]:
guess_player = (hangman_word[:i]) + word_chosen[i] + hangman_word[i + 1:]
print(guess_player)
continue
elif guess_player != word_chosen[i]:
guess += 1
Some issues:
The following assignment is wrong:
guess_player = (hangman_word[:i]) + word_chosen[i] + hangman_word[i + 1:]
You should not update guess_player which is the input letter. Instead you should update hangman_word. So:
hangman_word = (hangman_word[:i]) + word_chosen[i] + hangman_word[i + 1:]
The following condition will always be true when the execution gets there:
elif guess_player != word_chosen[i]:
The opposite was already checked in the preceding if statement, so the only possibility left is that the guess was wrong. No need to test that again.
guess += 1 should not appear within the loop. If the guess does not match the first letter, that doesn't mean it cannot still match with the second letter. So it is wrong to increment this counter when the comparison has not yet been made with all remaining letters of the secret word.
You can make use of the in operator to check whether there is at least one occurrence of the guessed letter:
if guess_player in word_chosen:
# ... here comes your loop to update `hangman_word` ... (without `elif`)
else:
guess += 1
The while loop should exit not only when the player has made five wrong guesses, but also if the player has found the word! You can do that as follows:
while guess < 5 and "_" in hangman_word:
When the while loop exits, you should probably report on the outcome of the game. Was it a success or not? It could be:
if "_" in hangman_word:
print("You guessed 5 times wrong. Game over.")
else:
print("You guessed the word. Well done!")
There should probably be some message when the player repeats a good guess a second time (optional).
Here is your code with corrections for the above points:
def guesses():
guess = 0
hangman_word = "_____"
while guess < 5 and "_" in hangman_word:
guess_player = input("What is your letter? ")
if guess_player in hangman_word:
print("But...but... you already guessed that letter!?")
elif guess_player in word_chosen:
print("Good going!")
for i in range(len(word_chosen)):
if guess_player == word_chosen[i]:
hangman_word = (hangman_word[:i]) + word_chosen[i] + hangman_word[i + 1:]
else:
print("That letter does not occur in the word.")
guess += 1
print(hangman_word)
if "_" in hangman_word:
print("You guessed 5 times wrong. Game over.")
else:
print("Well done!")
A couple aspects of the code can be improved.
def guesses():
# PreEnter the word for referece
word_chosen = "hangman"
guess = 0
# Creating a list instead of a string, to be able to update it, rather than creating new ones.
hangman_word = ["_" for _ in range(len(word_chosen))]
# Storing entered letters in a list for fair play in case wrong letters are entered.
entered_letters = []
while guess < 5:
guess_player = input("Enter a Letter: ")
# Checking if enterd string contains a single letter
if len(guess_player) > 1:
print("You can only enter one letter at a time.")
continue
if guess_player in entered_letters:
print("You already guessed that letter")
continue
# Using for loop only after checking if the letter is in the word.
elif guess_player in word_chosen:
for i in range(len(word_chosen)):
if guess_player == word_chosen[i]:
hangman_word[i] = guess_player
else:
print("That was an incorrect choice!")
guess += 1
# appending the entered letter to the list of entered letters.
entered_letters.append(guess_player)
# Using "".join to print the string from the list.
word = "".join(hangman_word)
print(word)
# Checking if the word is complete.
if word == word_chosen:
return "You Win!"
# If the player runs out of guesses, the game is over.
return "You Lose!"
print(guesses())
Since you are a beginner, try understanding the code through comments and see if you can figure out which aspects of your code I altered. Feel free to point out anything you have doubts about.

how do I stop a function to iterate through all items in a list

I am writing a simple word guessing game in python. Instead of using a list, I have all the words for the game in a .txt file called as the parameter of a function. The list itself is fine.
The game requires the user to enter a letter. Once the letter is entered, if it matched one of the words that is randomly selected by the random function, it gives points accordingly.
The problem is that when the function runs, the entered letter by the user iterates through all the words in the list. How do I fix this issue?
def guess_game(data):
word = random.choice(data)
print("alright, guess the first letter:")
ans = input("Enter a letter to guess: ")
print(ans)
counter = 0
tries = 15 #how many tries a user is allowed to make
for match in word:
if ans in match:
counter += 10
tries -= 1
print("That's right, 10 points added")
print(f"You have {tries} tries left. ")
elif ans not in match:
counter -= 10
tries -= 1
print("That's wrong, 10 points deducted")
print(f"You have {tries} tries left. ")
few ideas:
make a loop over your "tries" - the player can play until that is 0
the player has to provide the letter inside this loop
check for the letter provided by the player using
if ans in word
Here is my suggestion:
import random
print('Hi, welcome to the guessing game, wanna play?')
answer = input('Enter yes or no: ')
#just added a list to test
data = ['hello', 'coffee', 'tea']
word = random.choice(data)
if answer == "yes".lower():
print("OK, let's play")
print("alright, guess the first letter:")
counter = 0
tries = 15 # how many tries a user is allowed to make
while tries > 0:
ans = input("Enter a letter to guess: ")
print(ans)
if ans in word:
counter += 10
tries -= 1
print("That's right, 10 points added")
print(f"You have {tries} tries left. ")
elif ans not in word:
counter -= 10
tries -= 1
print("That's wrong, 10 points deducted")
print(f"You have {tries} tries left. ")
elif answer == "no".lower():
print("OK, have a good day")
else:
print('Please enter yes or no')
You could also make a list of letter that were already guessed so you can give the player feedback as soon as they found all the needed letters.
Not sure if I understand this completely, but if word is just a word like "apple" or "cat", then your function shouldn't be iterating through your entire list (your list being data). This function iterates through each letter of the randomized word (like "apple") and checks if the inputted letter is equal to any of the letters in that word.
The 'in' keyword itself checks only the first occurrence of a variable in a collection.
However if you want to be more specific, assign your entered word to a variable and then use break keyword after it matches under the if statement while iterating through the list.

How do I get the value of a variable to decrease by 1 every time the user enters something incorrect?

This is a python program exercise called guess the word from codehs.com. It basically works like hangman. The user has 10 lives and I'm trying to decrease the lives by one when the user guesses an incorrect letter. However, it always says there are 9 incorrect guesses remaining no matter how many times a user guesses an incorrect letter. How do I fix the program so that it decreases by one all the way down to 0 incorrect guesses left? Furthermore, how do I say that the user lost and terminate the program when he/she has zero incorrect guesses left? Thanks so much.
#initializes the secret word and starts with empty dashes list
secret_word = "eggplant"
dashes_list = []
def get_guess():
#prompts user for a guess
guess = input("Guess: ")
dashes = "-"
guesses_left=10
#if the guess is not one character
if len(guess) != 1:
print ("Your guess must have exactly one character!")
#if the guess is not lowercase
elif not guess.islower():
print ("Your guess must be a lowercase letter!")
#assigns this position_of_letter variable to be used later
position_of_letter = 0
for letter in secret_word:
if guess == letter:
print ("Letter is in secret word.")
update_dashes(secret_word, dashes, guess)
return
else:
position_of_letter += 1
if position_of_letter == len(secret_word):
print ("Letter is not in the secret word.")
if guesses_left==0:
print("You lose. The word was "+secret_word)
guesses_left-=1
print (str(guesses_left)+" incorrect guesses left.")
#This goes through the word and makes sure to update
#the dashes at the right place
def update_dashes(secret_word, dashes, guess):
position_of_letter_dashes_list = 0
for letter in secret_word:
if letter == guess:
dashes_list[position_of_letter_dashes_list] = guess
position_of_letter_dashes_list += 1
#adds a dash mark for each letter so there is now a list of dashes
for i in range(len(secret_word)):
dashes_list.append("-")
#The .join breaks the dashes list into a continuous string of dashes
#The "" is there so that nothing comes before each dash
while True:
print ("".join(dashes_list))
get_guess()
if "-" not in dashes_list:
print("Congrats! You win. The word was "+secret_word+".")
break
You are re-initializing number of guesses_left=10 each time so the value of guesses_left is not decreasing with every incorrect guess. You can initialize its value outside the get_guess() as a global variable or pass it as a parameter to this function.

How to store user inputted strings in a variable and then see if those inputs are contained in a word

I'm trying to make a hangman game. At the moment I'm still trying to figure out how to store users inputted strings in a variable.
I need this because if a user guesses the word before the ten guesses it keeps asking them for another letter.
I've tried creating a variable and then updating the variable as the user entered more letters. However that doesn't work in cases the user doesn't enter all the letters in the correct order the program is obviously not going to recognize this as the correct word.
Basically I need a way to store the inputted strings (one letter at a time) and to be able to check if all of those letters are contained in the five letter word.
import random
print("Welcome to hangman, guess the five letter word")
words =["china", "ducks", "glass"]
correct_word = (random.choice(words))
trials = 10
for trial in range(trials):
guess = input(str("Enter Character:"))
if (len(guess) > 1):
print("You are not allowed to enter more than one character at a time")
continue
if guess in correct_word:
print("Well done " + guess + " is in the list!")
else:
print("Sorry " + guess + " is not included")
It seems like a set is what you need.
You start with an empty set() and add the letter every time. To check if the letters are enough, use saved_set == set(correct_word).
With the help of an auxiliar list, this little guy will do the trick (I put some comments to better explain what I did):
import random
import sys
print("Welcome to hangman, guess the five letter word")
words =["china", "ducks", "glass"]
correct_word = (random.choice(words))
trials = 10
trial = 0
#the list starts empty, since the user didn't guessed any letter
guessed_letters = []
while(trial < trials):
guess = input(str("Enter Charcter:"))
if (len(guess) > 1):
print("You are not allowed to enter more than one charcter at a time")
continue
if (guess in correct_word) and (guess not in guessed_letters):
#once our user guesses a letter that he didn't guessed before, it will be added to our list of guessed letters
print("Well done " + guess + " is in the list!")
guessed_letters += guess
#in here we compare the size of the list with the size of the correct_word without duplicates
#if it's the same size, boom: the user won!
if (len(guessed_letters) == len(set(correct_word))):
print("Congratulations! You won!")
sys.exit()
else:
#just to avoid confusing the user with duplicate letters
if (guess in guessed_letters):
print("You already tried letter " + guess + "! Try another letter")
trial -= 1
else:
print("Sorry " + guess + " is not included")
print("Remaining chances: " + str(trials - trial))
trial += 1
print("\n\n\nGame over!!!!")
All you need is to replace:
guess = input(str("Enter Charcter:"))
by:
guess = str(sys.stdin.readline().rstrip('\n'))

Python while loop to test two true/false elements

I am working on a word jumble game for my kids. I want them to be able to type 'hint' into the guess in order to get a hint. The first 'hint' should give the first and last letters of the word. The next time they type 'hint' should provide the first two and last two letters of the word.. etc.
I have it working for the first time they type 'hint' but then the while loop is broken and they can't guess incorrectly or type 'hint' again.
I know the issue is with this line:
while guess != correct and guess != 'hint':
I just can't seem to fix it so that the user can type hint more than once.
Here is my code:
# The computer picks a random word, and then "jumbles" it
# the player has to guess the original word
import random
replay = "y"
while replay == "y":
print("\n"* 100)
word = input("Choose a word for your opponent to de-code: ")
print("\n"* 100)
# provide a hint if the user wants one
hint_count = 1
# create a variable to use later to see if the guess is correct
correct = word
# create a empty jumble word
jumble = ""
# while the chosen word has letters in it
while word:
position = random.randrange(len(word))
# add the random letter to the jumble word
jumble += word[position]
# extract a random letter from the chosen word
word = word[:position] + word[position +1:]
# start the game
print(
"""
Welcome to the Word Jumble!
Unscramble the letters to make a word.
(Press the enter key at the prompt to quit.)
"""
)
score = 10
print("The jumble is: ",jumble)
guess = input("\nType 'hint' for help but lose 3 points. \
\nYOUR GUESS: ")
while guess != correct and guess != 'hint':
print("Sorry that's not it.")
score -= 1
guess = input("Your guess: ")
if guess == 'hint':
print("The word starts with '"+ correct[0:hint_count]+"' and ends with '"+correct[len(correct)-hint_count:len(correct)]+"'")
score -= 3
hint_count += 1
guess = input("Your guess: ")
if guess == correct:
print("That's it! You guessed it!\n")
print("Your score is ",score)
print("Thanks for playing.")
replay = input("\n\nWould you like to play again (y/n).")
After the first 'hint' the program should ask for a guess and then continue on to print("Thanks for playing.") since the conditional to check for hint is outside of the while loop. Put it into the while loop:
while guess != correct:
if guess == 'hint':
print("The word starts with '"+ correct[0:hint_count]+"' and ends with '"+correct[len(correct)-hint_count:len(correct)]+"'")
score -= 3
hint_count += 1
guess = input("Your guess: ")
else:
print("Sorry that's not it.")
score -= 1
guess = input("Your guess: ")
The problem is that you check for guess == 'hint' outside the while loop. Try something like
while True:
guess = input(...)
if guess == correct:
# correct
break
elif guess == 'hint':
# show hint
else:
# not it, decrement score

Categories