I would like to find out where in 'words' the users 'guess' is, and then print the guessed character alongside '_' in the correct position:
words = "apple"
print("_ " *len(words), end="")
guessed = ""
for char in words:
guess = input("\n start guessing")
if guess in words:
for i in guess:
guessed += guess
else:
print("wrong letter")
The following should work:
word = "apple"
guessed = "_ " *len(word)
print(guessed)
while '_' in guessed:
guess = input("\nGuess a letter\n")
if len(guess) == 1:
if guess in word:
guessed = ' '.join([x if x == guess or x in guessed else '_' for x in word])
print(f"You guessed correct, the letter {guess} is in the word:\n{guessed}")
else:
print(f"Sorry, {guess} ist not correct.")
print('Congratulations, you solved it!')
I replaced the for with a while loop that exits, when there are no underscores left in the word the user has to guess. This allows the user to guess until the word is complete. If you want to limit the user to certain amount of guesses, you could add a counter variable and break the loop accordingly.
The script furthermore checks if the input is a single character with if len(guess) == 1:. The list comprehension then replaces underscores based on the condition that whether the user already guessed the character earlier on (x in guessed) or in this round (x == guess).
Note that this solution involving f-strings works in python versions >3.6. If you're using another python version, you'll have to replace the f-strings. In addition, I should mention that this code is case sensitive. So if your word starts with an uppercase letter and the user guessed the first letter but as a lowercase, the script will consider it as a wrong letter.
Related
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)
I'm trying to build a basic program where the computer selects a word out of a pre-existing list (called "words") and the user must guess the appropriate letters to guess the word. This is what the main function looks like so far:
def game():
word = random.choice(words)
while ' ' or '-' in word:
word = random.choice(words)
if ' ' or '-' not in word:
break
print(f'Hint: The chosen word is {len(word)} letters long')
letters = list(word)
progress = []
while True:
guess = str(input('Guess a letter: '))
if len(guess) > 1:
print('Sorry, guess a single letter: ')
if guess in word:
print(f'The letter {guess} is in the word')
for i, j in enumerate(letters):
if progress.count(guess) >= letters.count(guess):
break
elif j == guess:
progress.insert(i, j)
print('Current progress: ' + '-'.join(progress))
if len(progress) == len(word):
if letters[:] == progress[:]:
print('Congrats! You found the word: ' + str(word))
break
elif guess not in word:
print(f'The letter {guess} is not in the word: Try Again')
continue
My issue is with the for loop where I use enumerate(y) and the respective "elif j == guess" condition. I noticed that when running the function, the code works if the letters that are repeated are successive (ex: in the word "chilly", if I type in "l", the function correctly displays the two l's and the game works as intended). However, if the letters are repeated separately (ex: the word "cologne"), the function doesn't insert the "l" between the two o's, and keeps the two o's together regardless, thus preventing the proper word from ever being guessed. Is there a different method I could use to fix this problem?
You should remember the letters already guessed and simplyfiy the printing to any letter that you remember and use - for any other letter in the word.
Your errror stems from your list and counting method to remember which letters to print or not.
I fixed your incorrect if-condition (see How to test multiple variables against a value? for more on that).
import random
# supply list of words to function to avoid globals
def game(words):
word = random.choice(words)
# fixed your check ... not sure why you do that
while ' ' in word or '-' in word:
word = random.choice(words)
# no break needed, will break if no space/- in
print(f'Hint: The chosen word is {len(word)} letters long')
# remember which letters where guessed already
guesses = set()
while True:
guess = input('Guess a letter: ') # no str needed it is already a str
if len(guess) > 1:
print('Sorry, guess a single letter: ')
continue # back to while loop
# add to guessed letters
guesses.add(guess)
# print message
if guess in word:
print(f'The letter {guess} is in the word')
else:
print(f'The letter {guess} is not in the word: Try Again')
continue # back to while loop
print('Current progress: ', end="")
# assume we have all letters guessed
done = True
for idx, letter in enumerate(word):
if letter in guesses:
# print letter if already guessed
print(letter, end="")
else:
# invalidate assumption and print -
done = False
print("-",end="")
print()
# if assumption not invalidated: done
if done:
print('Congrats! You found the word: ' + str(word))
break
game(["eye", "ear", "egg", "anvil"])
Output:
Hint: The chosen word is 3 letters long
Guess a letter: The letter e is in the word
Current progress: e-e
Guess a letter: The letter r is not in the word: Try Again
Current progress: e-e
Guess a letter: The letter y is in the word
Current progress: eye
Congrats! You found the word: eye
I have been looking around to see if I could find something that could help, but nowhere has an answer for what I'm looking for. I have a Hangman game I'm doing for a final project in one of my classes, and all I need is to make it so if a word has a capital letter, you can input a lowercase letter for it. This is the code.
import random
import urllib.request
wp = "http://svnweb.freebsd.org/csrg/share/dict/words?view=co&content-
type=text/plain"
response = urllib.request.urlopen(wp)
long_txt = response.read().decode()
words = long_txt.splitlines()
###########
# Methods #
###########
def Run():
dashes1 = "-" * len(word)
dashes2 = "-" * len(word2)
used_letter = []
dashes = dashes1 + " " + dashes2
#dashes ="-" * len(secretWord)
guessesLeft = 6
while guessesLeft > -1 and not dashes == secretWord:
print(used_letter)
print(dashes)
print (str(guessesLeft))
guess = input("Guess:")
used_letter.append(guess)
if len(guess) != 1:
print ("Your guess must have exactly one character!")
elif guess in secretWord:
print ("That letter is in the secret word!")
dashes = updateDashes(secretWord, dashes, guess)
else:
print ("That letter is not in the secret word!")
guessesLeft -= 1
if guessesLeft < 0:
print ("You lose. The word was: " + str(secretWord))
print(dashes)
else:
print ("Congrats! You win! The word was: " + str(secretWord))
print(dashes)
def updateDashes(secret, cur_dash, rec_guess):
result = ""
for i in range(len(secret)):
if secret[i] == rec_guess:
result = result + rec_guess
else:
result = result + cur_dash[i]
return result
########
# Main #
########
word = random.choice(words)
word2 = random.choice(words)
#print(word)
#print(word2)
secretWord = word + " " + word2 # can comment out the + word2 to do one
word or add more above to create and combine more words will have to adjust
abouve in Run()
splitw = ([secretWord[i:i+1] for i in range(0, len(secretWord), 1)])
print (splitw)
Run()
any bit of help is appreciated. The website I'm using has a bunch of words that are being used for the words randomly generated. Some are capitalized, and I need to figure out how to let the input of a letter, say a capital A, accept a lowercase a and count for it.
you could compare after you converted everything to lowercase.
e.g. you could do
secretWord = word.lower() + " " + word2.lower() # that should make your secret all lowercase
for the input you should do the same:
guess = input("Guess:").lower()
after that it should not matter if it is upper or lower case. it should always match if the letter is the correct one.
hope that helps
Simply check everything in lowercase:
[...]
elif guess.lower() in secretWord.lower():
[...]
and so on.
I would just change this line:
while guessesLeft > -1 and not dashes == secretWord:
to:
while guessesLeft > -1 and not dashes.lower() == secretWord.lower():
This way you are always comparing lower-case representations of the user's input to the lower-case representation of your secretWord. Since this is the main loop for your game, you want to break out of this as soon as the user's guess matches your word regardless of case. Then later in your code, you will still check whether they had any guesses left, and print out their answer and the secret word as before.
No other changes required, I think.
You could just force all comparisons to be made in the same Case, such as lowercase.
Let’s say that your word is "Bacon". and someone enters "o".
That will be a match because quite obviously “o” equals “o” so you can cross that letter off the list of letters left to guess.
But in the case that someone enters “b” then b is NOT equal to “B”.
So why not just force all letters to be compared using the same case?
So your comparison will be like
elif guess.Lower() in secretWord.Lower()
My python is rusty as hell, but the idea here should do what you want to do
I'm currently learning Python and trying to build a set of minigames to solidify my basic knowledge, however there are a few things I want to do with my game that others on here haven't (from what I've seen, at least), and that is remove whitespace between words from the answer and the "masked" answer. I assume it would be done as an "if, else" sort of statement? Please correct me if I'm wrong.
for x in range(i): ## where i is the word
if x == " ":
continue ## wouldn't it be pointless to append something that you don't want to change?
else:
word.append('_')
Another question I had was regarding a loop statement I have at the beginning of my game, within this loop I have an if/else stating that if there are more than 1 letter in the guess, it'll return a statement telling the user that's not valid. But the game immediately stops working afterword.
while guesses < 6:
guess = raw_input("Please guess a letter: ")
if len(guess) > 1:
return "One letter at a time!"
else: continue
I'm not quite sure what to add to my code to make it continue asking for input after this.
Here's my full code, it's currently not working for me after asking for input... I took the code it from another user on here and fixed it to my tastes, since their game didn't use more than one word and didn't check to see if there was more than one letter being input when prompted, and I figured it would be good practice to modify existing code to make it do a bit more than it originally does.
def hangman():
guesses = 0
word = []
guessed = []
words = ["bichon frise", "maltese", "dachshund", "pomeranian", "golden retriever", "shih tzu", "rottweiler", "pit bull", "beagle", "poodle", "akita", "basset hound", "border collie", "boston terrier", "boxer", "bulldog", "chow chow", "chihuahua", "chinese crested", "french bulldog", "great dane", "great pyrenees", "greyhound", "icelandic sheepdog", "irish wolfhound", "komondor", "mastiff", "shnauzer", "pekingese", "welsh corgi", "redhound coonhound", "samoyed", "shiba inu", "weimaraner", "whippet", "italian greyhound", "yorkshire terrier"]
print "Welcome to Hangman. The words chosen are the names of various breeds of dogs, try and guess the word before the man is hung!"
answer = random.choice(words)
i = len(answer)
print "The length of the word is", i, "characters long"
for x in range(i):
if x == " ":
continue
else:
word.append('_')
while guesses < 6:
guess = raw_input("Please guess a letter: ")
if len(guess) > 1:
return "One letter at a time!"
else:
continue
if (guess in i):
print "The letter is in the word."
for index, letter in enumerate(i):
if letter == guess:
word[index] = guess
guessed.append(guess)
else:
print "The letter is not in the word"
guesses = guesses + 1
guessed.append(guess)
print "You have guessed these letters so far: %s)" % (''.join(guessed))
print "Letters matched so far %s): %" (''.join(word))
if ''.join(word) == answer:
break
if guesses == 6:
print "You didn't guess the right answer in time! The answer was %s" % answer
else:
print "You guessed the word!"
remove whitespace between words from the answer.
Given i (i as a string?) is the string, you probably should not use range(..) on it since range expects an int. Furthermore why do you build a list instead of a new string? You can however easily use a generator:
word = ''.join(c for c in i if c != ' ')
word is here a string that contains all characters of i that are not ' '. If you want however to generate a sequence of underscores, you can use:
word = ''.join('_' for c in i if c != ' ')
If you want to construct a list (which the remainder of the code expects), you can use list comprehension:
word = ['_' for c in i if c != ' ']
it'll return a statement telling the user that's not valid. But the game immediately stops working afterword (sic.).
That's because you use a return statement: return means you jump out of the function and (optionally) return a value. You probably want to print(..):
guesses = 0
while guesses < 6:
guess = raw_input("Please guess a letter: ")
if len(guess) > 1:
print("One letter at a time!")
else:
#process char
continue
I also noticed you use continue. continue means that you abandon the remainder of the iteration and take the next one, so it means you will not process the query. So you have to remove the continue part:
while guesses < 6:
guess = raw_input("Please guess a letter: ")
if len(guess) > 1:
print("One letter at a time!")
return ends the function right there, use print instead:
print "One letter at a time!"
As for the whitespace, why don't you append the space to the masked word? That way, the player won't have to guess it, can see that there are spaces, and your join-check will work:
for x in range(i):
if x == " ":
word.append(' ')
else:
word.append('_')
I'm in a basic programming class and I'm a bit stuck working on this game. The idea was to create a simple word-guessing game, where the computer would choose a random word and you would attempt to guess first some letter in the word, then the word itself after 5 tries. I've gone through multiple times and I still get an error of "Invalid Syntax" when I attempt to run the module.
I'm a bit dyslexic when it comes to programming languages, so maybe there's something I'm overlooking?
I would appreciate it if someone out there could offer a bit of help!
#Word Guessing Game
#Computer picks a random word
#Player tries to guess it
#computer only responds with yes or no
import random
tries = 0
print "Welcome to the word game!"
print "\nI'm going to think of a word and you have to guess it!"
print "\nGuess which letters are in the word, then you have to guess the whole thing!"
print "\nGood luck!"
WORDS = ("follow", "waking", "insane", "chilly", "massive",
"ancient", "zebra", "logical", "never", "nice")
word = random.choice(WORDS)
correct = word
length = len(word)
length = str(length)
guess = raw_input("The word is " + length + " letters long. Guess a letter!: ")
while tries < 5:
for guess in word:
if guess not in word:
print "Sorry, try again."
else:
print "Good job! Guess another!"
tries = tries + 1 #*
if tries = 5:
final = raw_input ("Try to guess the word!: ")
if final = correct:
print "Amazing! My word was ", word, "!"
else:
print "Sorry. My word was ", word, ". Better luck next time!"
raw_input("\n\nPress enter to exit")
It should also be noted that the problems occurred after the end of the "while tries" block, when I attempted to specify the limits of the "tries" variable. I've worked with it before in a random number game, but for some reason it didn't work properly here. I would greatly appreciate some help!
It should also be noted that I run on a rather outdated version of Python, some variation of 2.0, I believe.
tries = tries + 1
if tries == 5:
final = raw_input ("Try to guess the word!: ")
if final == correct:
You need == for comparison not =, = is for assignment.
You can also replace tries = tries + 1 with tries += 1
You also want to move raw_input inside the loop and just ask the user to guess the word outside the while when the guesses are all used up:
while tries < 5:
guess = raw_input("The word is " + length + " letters long. Guess a letter!: ")
if guess not in word: # use `in` to check if the guess/letter is in the word
print "Sorry, try again."
else:
print "Good job! Guess another!"
tries += 1
# guesses are all used up when we get here
final = raw_input ("Try to guess the word!: ")
if final == correct:
print "Amazing! My word was ", word, "!"
else:
print "Sorry. My word was ", word, ". Better luck next time!"
please try this one.
import random
index = -1
infi = ("python","jumble","hide","mama")
word = random.choice(infi)
word_len = len(word)
guess = ""
attempt = 0
enter = ""
print(word)
temp = "_" * word_len
print("\t\t The word chosen by computer contain", word_len,"letters.")
print("\t Tap any letter to check if this letter is in computer word.\n")
print("\t You got 5 attempts to check if tapped letter is in computer word.\n")
print("\t\t\t\t GOOD LUCK!!!\n\n\n\n")
for i in range(0, 5):
attempt +=1
guess = input("Attempt no. "+str(attempt)+":")
if guess in word and guess != enter:
for i in range(0, word_len):
if guess == word[i]:
temp = temp[:i] + guess +temp[i+1:]
print("yes\n" + temp)
if guess not in word:
print("no")
if "_" not in temp:
print("\t\t*********** Congratulation!! You guess the word *************")
break
elif attempt == 5:
guess = input("And the word is:")
if guess == word:
print("\t\t*********** Congratulation!! You guess the word *************")
else:
print("\t\t*********** WRONG!! Shame on you *************")