Python 3.2 Hangman String edit - python

This is my code for a school hangman project. I currently have some trouble with editing my correctguess string.
I have been told that strings in Python are immutable, but with that fact I now don't know how to add the correctly guessed letter to my guesses. I was originally thinking of using the find method, but now I feel like that won't work. If possible, I'd like a solution or a recommendation for creating a string that is editable, or a loop to create new strings. I'd like it so that every time I get a correct guess, (let's say A) my "HANGMAN" (which is my code word) would change from "XXXXXXX" to "XAXXXAX".
(Sorry that this is hard to explain, the code should be easier to understand, as I added a lot of comments as to what I want to do. I also commented out some code that gave me errors.)
Thanks in advance
import sys
message1=("hangman")
l=len(message1)
t = 10
c = 0
tries = str(t)
correct = str(0)
wrongguess=" "
print("Hello, you have 10 tries to achieve the answer.")
for i in range(0,l):
sys.stdout.write('x')
i=i+1
print("")
for x in range(0,l):
message2=input()
message3= message2.lower()
finder = message1.find(message3)
if(int(finder)==-1):
print("You Fail")
if(int(finder)!=-1):
correctguess[int(finder)]=message2
print(correctguess)
## find message 3 within message 1
## "Find" the input message within the original hangman word; Find the position
## of the "Found" letter within the original message, and replace the "correctguess"
## string's position of the Found letter; The found letter. If not, tries will -1,
## if tries = 0, terminate program
## Create an input loop that will save under a new string. If the input does not equal
## to anything within the original word, add the letter to the "wrongguess" string
##for x in range(0, l-1):
## message2=input()
## message3= message2.lower()
## if message3==message1[x]:
## correctguess[x]= message3
## print(correctguess)
## if message3!=message1[x]:
## t=t-1
## if t==0:
## print("You lose")
##
##if message1==message3:
## print("Correct! You had " + tries + " tries left, and had " + correct + " correct")
##

I just wrote up a hangman game right now to test, and what worked for me was this:
word was the word that the user had to guess.
I had a mask, which is a list with the same length as word. mask consists of only 1s and 0s. If an index of mask is 1, then show the user has guessed that letter. If it's 0, the user hasn't guessed it.
Example usage:
word = 'hangman'
mask = [0]*len(word)
# How to print the obfuscated word
# Print X if the user hasn't guessed the letter, otherwise print the letter.
print(''.join('X' if mask[i] == 0 else word[i] for i in range(len(mask))))
# How to get the guess
guess = input().strip().lower()[0]
# How to mark the guessed letter in the word
if guess in word:
mask = [1 if mask[i] == 1 or word[i] == guess else 0 for i in range(len(mask))]
Also, I see you iterate through the game with range(0,l) where l = len(word). Instead you should use a while loop, like so:
guessed = False
tries = 10
while (not guessed) and (tries > 0):
# Play game
That way, the game will end if the user guesses correctly, or if the user runs out of tries. After the game, whether the user won or not can be gotten simply by checking the value of guessed
Pseudocode:
Set the word
init the mask to the length of the word
set tries to the number of guesses the playe rhas
set guessed to False
while not guessed and tries > 0:
get guess from input
if guess in word:
update mask to mark the guessed letters
if the mask is full of 1s, (if the sum of mask is equal to the length):
guessed = True
else:
tries -= 1
if guessed:
The user has correctly guessed the word
else:
The user has failed.

if you want to edit a string, you could use a list in conjunction with the string.join method instead. The join method takes a list as an argument and returns a string which is separated by the original string. If you make it an empty string, you'll get the string you need.
my_word = ["H", "E", "L", "L", "O"]
''.join(my_word)
# 'HELLO'
my_word[1] = "H"
''.join(my_word)
# 'HHLLO'

Related

10.1.3 Guess the Word, Part 2 Help Needed

I am currently stuck on exercise 10.1.3 on CodeHS, which is essentially a part in making a hangman game, without the hangman. I have my code nearly complete for this section of the game, yet for some reason whenever new input is given (for a letter), it clears previous input.
Here is my code:
secret_word = "character"
dashes = "-" * len(secret_word)
print(dashes)
#Prints the first row of dashes to indicate word length
def get_guess():
while True:
guess = input("Guess: ")
if isinstance(guess, int):
print("Your guess must be a lowercase letter.")
else:
if guess.islower():
if len(guess) == 1:
return guess
else:
print("Your guess must have exactly one character.")
def update_dashes(secret_word, dashes, guess):
result = ""
for i in range(len(secret_word)):
if secret_word[i] == guess:
result = result[:i] + guess + result[i + 1:]
else:
result = result + "-"
return result
while True:
guess = get_guess()
if guess in secret_word:
print("The letter is in the word.")
else:
print("That letter is not in the word.")
print(update_dashes(secret_word, dashes, guess))
#We believe the issue is here, it is printing the full set each time this loops.
When run, this is the output:
---------
Guess: c
The letter is in the word.
c----c---
Guess: h
The letter is in the word.
-h-------
Guess:
The code should be adding the "h" to the word, yet it is 'overwriting' what is already there.
This is what I want it to print:
---------
Guess: c
The letter is in the word.
c----c---
Guess: h
The letter is in the word.
ch---c---
Guess:
Note that the word that should be guessed is "character".
And finally, this is the part of the assignment that relates to what the current problem is:
Step 2 - Update the Dashes
Here’s the tricky part. Write a function called update_dashes that
takes three string arguments - the secret word, the current state of
dashes, and the most recent guess - and returns the new state of
dashes.
So, for example, if the word is "eggplant", the current value of
dashes is "e-------", and the guess is "g", the function should return
"egg-----".
If the word is "eggplant", the current value of dashes is "e-------",
and the guess is "z", the function should return "e-------" (nothing
changes, since the guess was incorrect).
Here’s how you might go about this.
In your function, start with an empty result string. Write a for loop
from 0 up to but not including the length of your secret word. Say you
use the variable i in your for loop. Compare the character in
secret_word at index i to the guess. If they’re equal, then that means
the guess matches that letter in the word, so you should add the guess
to the result. Otherwise, the guess does not match that letter in the
word, so you should add whatever was at index i in dashes to your
result.
Wait, why don’t I just add a dash in the second case?
If you just add a dash whenever the guess doesn’t match the character
in secret_word at index i, that will wipe out any correct guesses the
user has already made! Imagine the case where the word is “eggplant”,
the state of dashes is “e——-“, and the guess is “g”. If you always add
a dash when the guess doesn’t match the character in secret_word at
index i, the result would be “-gg—–”. Suddenly, the “e” is gone,
because “g” did not match “e”! By instead using dashes at index i, you
might append either a letter or a dash, depending on whether or not
the user had already guessed that letter prior to the current guess.
Once your for loop is done, your result string should have letters and
dashes in all the right places, so you can just return it!
As the instructions say, when the guess doesn't match you should add the corresponding element of dashes to the result, not just a dash. You need to do this so that all the previous correct guesses are copied to the result.
def update_dashes(secret_word, dashes, guess):
result = ""
for i in range(len(secret_word)):
if secret_word[i] == guess:
result += guess
else:
result += dashes[i]
return result
Additionally, your main loop has to assign the result back to dashes so it accumulates all the correct guesses.
while True:
guess = get_guess()
if guess in secret_word:
print("The letter is in the word.")
dashes = update_dashes(secret_word, dashes, guess)
else:
print("That letter is not in the word.")
print(dashes)

Why is this loop not working, also how do I make the code remember the previous letters guessed?

Im new to programming and was trying to program a word guesser. I dont understand why the while loop doesnt go though three times, also the program doesnt remember the previously guessed letters.
import random
words = ["hello", "bye", "petscop"]
GuessWord = random.choice(words)
tries = 3
while tries > 0:
tries = tries - 1
inp = input("\nEnter your guess: ")
for char in GuessWord:
if char in inp:
print(char, sep="",end="")
elif char not in inp:
print("_", sep="",end="")
tries = tries - 1
I'm sorry to say, StackOverflow isn't a forum for debugging. StackOverflow is more about solving general problems that affect multiple people rather than single instances of a problem (like bugs), if that makes sense.
There is probably a better place for you to ask this question but I can't think of one off the top of my head.
In the spirit of being constructive: the following code appears twice and you should remove the second instance.
tries = tries - 1
Also, you are overwriting inp each time you enter the loop causing it to forget its previous value. There are other issues too. But that's a good start.
The main problem you have is that you decrease the number of tries by 2 each round. Therefore, at the beginning of the second round, the number of tries decreases again so it fails. This is how I would do it:
import random
# library that we use in order to choose
# on random words from a list of words
name = input("What is your name? ")
# Here the user is asked to enter the name first
print("Good Luck ! ", name)
words = ['rainbow', 'computer', 'science', 'programming',
'python', 'mathematics', 'player', 'condition',
'reverse', 'water', 'board']
# Function will choose one random
# word from this list of words
word = random.choice(words)
print("Guess the characters")
guesses = ''
# any number of turns can be used here
turns = 3
while turns > 0:
# counts the number of times a user fails
failed = 0
# all characters from the input
# word taking one at a time.
for char in word:
# comparing that character with
# the character in guesses
if char in guesses:
print(char)
else:
print("_")
# for every failure 1 will be
# incremented in failure
failed += 1
if failed == 0:
# user will win the game if failure is 0
# and 'You Win' will be given as output
print("You Win")
# this print the correct word
print("The word is: ", word)
break
# if user has input the wrong alphabet then
# it will ask user to enter another alphabet
guess = input("guess a character:")
# every input character will be stored in guesses
guesses += guess
# check input with the character in word
if guess not in word:
turns -= 1
# if the character doesn’t match the word
# then “Wrong” will be given as output
print("Wrong")
# this will print the number of
# turns left for the user
print("You have", + turns, 'more guesses')
if turns == 0:
print("You Loose")

One iteration is being wasted, and not getting proper output. (Python)

I am beginner in python and trying to make a simple game in which the user has to guess the word/name by inputting characters of that word/name. The program will generate stars of the word length which the user has to guess.
When the user will input a character, the position of that character in stars will be changed to that character. For example, The word is my name "Vishwas", the program will generate 7 stars as the length of my name is 7, *******, when user will input i the output will be Correct *i***** like this.
Now the problem is my name has two 's' in it, the program is okay till 2 's' but when we input third 's' as input it just wastes that iteration, I want here output as "Incorrect" which I just don't know how to fix here otherwise all the code is okay.
Also, tell what function to use to let the program wait till the user inputs a character as C++ has getch function right now I have used time function.
import time
print("\t\t\t\t\t\t\tWelcome to name guessing game")
name = "shahzaib"
LengthOfWord = len(name)
stars = []
for x in range(LengthOfWord):
stars.append("*")
stars = ''.join(stars)
print(stars)
print("Enter a character")
chance = 2
y=0
LOW=LengthOfWord
while y < LOW:
if chance<0:
print("Game Over")
break
chr = input()
chr = chr.lower()
count = 0
for x in range(LengthOfWord):
if chr[0] == name[x]:
if stars[x] == name[x]:
continue
else:
stars = list(stars)
stars[x] = chr[0]
stars = ''.join(stars)
print("Correct\n",stars)
if stars == name:
print("Congratulations you won")
break
count+=1
if count == LengthOfWord:
print("Incorrect\n",chance,"Chance(s) left\n",stars)
chance -= 1
LOW=LOW+1
y+=1
time.sleep(3)
The program is pretty simple I think it should be easily understandable.
Your logic is too much complex, you don't have to use any time class to wait for user to input, in python we use input() simple. It will wait till infinity for user to input something.
This can be done simply like this:
name = 'shahzaib'
chances = 3
stars = ['*' for _ in name] # I kept it as a list so that we can replace * with char
print("\t\tWelcome to name guessing game")
# while there are chances and user hasn't guessed the whole name
while chances > 0 and '*' in stars:
user = input("\nEnter Character: ").lower()
# If correct
if user in name:
index = name.find(user) # find the first occurence of that char in name
name = name.replace(user, '.', 1) # now replace that char with some special character like '.'
stars[index] = user # replace the value in the stars list so that we can show it to the user
print("Correct\nName: " + ''.join(stars))
else:
chances -=1
print("Incorrect, {} chances left.".format(chances))
Your problem is when you have more than 1 occurrence of the same character in name. This problem arose because of your logic.
The solution as you can see is to replace the occurrence of the character with some special letter like . , :, ; etc, that will not be used in a name. This will also make the program more elegant as you will be guessing the character from left to right.
Ask me anything if you feel confused about the code.

How to reveal a specific letter in a string for Python?

I am in high school and am currently teaching myself Python. I am programming Hangman and it is going well so far (it is not very organized yet) but I am having a problem. I created a list of words that I would use for the game and replaced them with asterisks using the range function. Here is the code for that:
words = ['utopia', 'prosecute', 'delirious', 'superficial', 'fowl', 'abhorrent', 'divergent',
'noxious', 'scarce','lavish', 'hinder', 'onerous', 'colossal', 'infringe']
picked_words = random.choice(words)
for i in range(len(picked_words)):
print(picked_words.replace(picked_words,'*'), end = '')
I am at the point where I am guessing the letters and I need to slowly reveal the position of certain letters. I have tried looking for certain functions (I even thought that the find() function would work since it prints the location of a letter in a string but it did not) and I am at a loss. Especially for words with multiples of the same letter such as "onerous" and "infringe." I will write the code that I have so far for this section:
def right_letter(correct):
if correct == True:
print("There are {} {}'s.".format(number_of_char, guess))
for x in range(len(picked_words)):
print(picked_words.replace(picked_words,guess, #find way to fill in specific letters),end = '')
I have no clue what parts of the code are necessary to get an answer but my code is really unorganized because I do not know proper techniques yet. The portion that says for x in range(len(picked_words))... is where I am having trouble. The rest of the code ran fine before I added the print statement underneath it. Basically I am asking how to change a certain character or specific characters and put them where they belong. For example, if the randomized word was "infringe" and the first guess was "i" how do I go from ******** to i***i***?
Also, in case anyone was wondering what I originally thought the solution was...
picked_words[(picked_words.find(guess))]
I thought that it would simplify and become picked_words[index]
Here's an example of converting your code to the hangman game.
Note how variable display in the code is updated to show user the correct guessed letters.
import random
def hangman():
words = ['utopia', 'prosecute', 'delirious', 'superficial', 'fowl', 'abhorrent', 'divergent',
'noxious', 'scarce','lavish', 'hinder', 'onerous', 'colossal', 'infringe']
max_guesses = 5
word = random.choice(words)
guesses = 0
display = "*" * len(word)
print(display, " Is the word")
while guesses < max_guesses:
letter = input("Please Enter Your guess letter: ")
if letter.lower() not in word:
guesses += 1
print("You got it incorrect, you have: ", max_guesses - guesses , " 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!")
return
hangman()
Basically you will need to find a partial match between your letter and the word here.
The easiest way i can think of is Pythons in Operator. It can be used like this
if picked_letter in picked words
% here you need to figure out at which position(s) the letter in your word occurs
% and then replace the * at the correct positions. A nice way to do this is
% the use of regular expressions
picked_words = re.sub('[^[^picked_letter]*$]', '*', picked_words)
%this will replace every letter in your word with the Asterisk except for the one picked
else
%do Nothing
Note that running this Code in a loop would replace every character in your string except the picked one EVERY time., therefore it is probably best to design your picked_letter as a list containing all characters that have been picked so far. This also makes it easier to check wether a letter has already been entered.

Notify user when they got a letter correct in a char list Python

How would I go about telling the user when they've got the correct letter in a list? Only way I know of is to insert the index, but that doesn't feel very flexible, especially when the words vary in length.
import random
possibleWords = [["apple"], ["grapefruit"], ["pear"]]
randomWord = random.choice(possibleWords)
anotherWord = ''.join(randomWord)
finalWord = list(anotherWord)
maxTries = list(range(0, 11))
attemptsMade = 0
triesLeft = 10
print("Hangman!")
print("\nYou got {} tries before he dies!".format(maxTries[10]))
print("There's {} possible letters.".format(len(finalWord)))
for tries in maxTries:
userChoice = input("> ")
if userChoice == finalWord[0]:
print("You got the first letter correct! It is {}.".format(finalWord[0]))
else:
print("Ouch! Wrong letter! {} tries remaining.".format(triesLeft))
attemptsMade += 1
triesLeft -= 1
Talking about characters in lists, or - what i think is more likely in your case - chars in words you can just check for
if userChoice in finalWord:
# [...] do stuff here
and further on use the index function to determine the position (or positions if multiple occurence).
finalWord.index(userChoice)
You could sure also go the way using index() function directly and work your way using the return values.
Use Python's "in" keyword to check if something is within a list/iterable.
if userChoice in finalWord:
Though for this, I'd just use regex or list comprehension to get the indexes while you are at it, since you might want them for the game.
char_indexes = [i for (i, l) in enumerate(finalWord) if l == userChoice]
if len(char_indexes):
Use a set for the letters that are in the word, and whenever the player guesses a letter, check if the letter is still in the set. If it’s not, it was a wrong letter; if it is, then remove that letter and just continue. If the set is empty at some point, then the player guessed all letters of the word.
Something to get you started:
def hangman (word):
letters = set(word.lower())
attempts = 5
while attempts > 0:
guess = input('Guess a character ')
if guess[0].lower() in letters:
print('That was correct!')
letters.remove(guess[0])
else:
print('That was not correct!')
attempts -= 1
if not letters:
print('You solved the word:', word)
return
hangman('grapefruit')

Categories