Coding Hangman in Python - python

I'm having trouble with this hangman coding. When I run the code, it asks the question "Type in a letter a - z", but when I type in a letter, instead of it putting a letter, it just ask the same question from the beginning without letting me know if the letter is correct or not.
import random
possibleAnswers = ["page","computer","cookie","phishing","motherboard","freeware","bus","unix","document","hypertext","node","digital","worm","macro","binary","podcast","paste","virus","toolbar","browser"]
random.shuffle(possibleAnswers)
answers = list(possibleAnswers[1])
display = []
display.extend(answers)
for i in range(len(display)):
display[i] = "_"
print ' '.join(display)
print "\n\n\n\n"
count = 0
while count < len(answers):
guess = raw_input("Type in a letter a - z: ")
guess = guess.upper()
for i in range(len(answers)):
if answers[i] == guess:
display[i] = guess
count += 1
print ' '.join(display)
print "\n\n\n"

It does tell you, after a fashion. The problem is that your entire word list is lower-case, but you specifically change all of your input guesses to upper-case. Those cannot match, so there's never a "correct" guess. Change the word list to capitals, or change your conversion from upper to lower.

Related

How do I have a list accept lowercase in place of capitalized letters in Hangman for a randomized list in Python 3?

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

python having a hard time at my letter guessing game

I'm trying to do a guessing game in python but I cant figure some stuff out. I have to enter a word and it will print a lot of spaces and the person is suppose to guess the word. It has to look like this after the word it's been typed. The user will enter a letter and is suppose to look like this (word is dog):
Enter a letter: a
So far you have:
***
if they guess the "o" for example, it will replace the * with an 'o' and so on until you get all the words right. And that's what I can't figure out, can somebody please help me? here is my program for far:
def main():
letters_guessed = set()
# Read word
word = input("\n Please Enter a word: ")
# print 100 spaces
print("\n" * 100)
# Storing the length of the word
word_length = len(word)
guess = '*' * word_length
while True:
print ("So far you have: ",
guess_letter = input ("Please guess a letter: ")
if len(guess_letter) != 1:
print ("Please guess one letter at a time")
if guess_letter in letters_guessed:
print ("\n You already guessed that letter, please try again")
letters_guessed.add(guess_letter)
if set(word) == set(letters_guessed):
break
print("You won, the word is " % word)
Somebody tried to help me but I just didn't understand how this works because I am new to the program, I want to be able to understand it also. Thank you. Here it was his output, just part of it.
while True:
print ("So far you have: ", "".join([c if c in letters_guessed else "*"
for c in word]))
guess_letter = input ("Please guess a letter: ")
I'll first explain the solution code you received. The following code:
[c if c in letters_guessed else "*" for c in word]
generates a list. If you see square brackets [ and ] , then we're list likely creating a list.
now what your friend is using is a generator. It's a short way of creating a for loop. In other words, this would do the same thing.
word = "dog"
letter_guessed = "go"
ourList = list() #new list
for letter in word: #we check every letter in the word
if letter in letter_guessed: #if our letter has been guessed
ourList.append(letter) # we can show that letter in our word
else:
ourList.append("*") # if the letter has not been guessed, we should
# not show that letter in our word, and thus we change it to a *
print(ourList)
This gives us the following list: ["*", "o", "g"]
What your friend then does, is take that list, and use join:
"".join[ourList]
This is a good way of turning a list of letters back into a string.
See: https://www.tutorialspoint.com/python/string_join.htm
Your own code has a few problems. Is it possible you didn't copy everything?
In python, using tabs effects the way your program runs. Because you put a tab before
print("You won, the word is " % word)
you'll run this line every single time, rather than only when the break statement is activated!
You have a similar problem with .add! Try to see if you can't spot it yourself.
I also recommend writing
print("You won, the word is " + word)
because this is much easier to use. (for more advanced formatting, look up .format() see https://pyformat.info/

How to replace "-" with a space?

I'm making a hangman program, and I want it to be able to include phrases; however, when I input a phrase to be guessed, the output only dashes. For instance, when I put in "how are you"(input to be guessed), the output is "-----------". What i want the out put to be is "--- --- ---", as it makes it easier for the player to know that it is a phrase. I've tried a 'for' loop and 'if' statement to now avail, and would appreciate some help. Thanks!
*At the moment I'm trying replace. Also, if this is badly worded, let me know and I'll try rewriting it.
right = ""
guess=""
attempts = 6
tries = 0
space = " "
print("Hangman: guess letters until you can guess the word or phrase.")
print("In this game you get six tries.")
right_str = str(input("\nEnter your word: "))
right_str = right_str.lower()
#displays the proper amount of unknown spaces
right = right * len(right_str)
if space in right_str:
right_str.find(space, i)
print(i)
you could try this:
guess=""
attempts = 6
tries = 0
space = " "
print("Hangman: guess letters until you can guess the word or phrase.")
print("In this game you get six tries.")
right_str = str(input("\nEnter your word: "))
right_str = right_str.lower()
output = ""
for c in right_str:
if c != " ":
output += "-"
else:
output += " "
print output

Python hangman, removing blanks from the answer pool and refining what can be input

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

python improving word game

Im working on a word game. The purpose for the user is to guess a 5 letter word in 5 attempts. The user can know the first letter. And if he doesn't get the word correct, but if he has a letter in the correct place he gets to know this.
This is my code:
import random
list_of_words = ["apple","table", "words", "beers", "plural", "hands"]
word = random.choice(list_of_words)
attempts = 5
for attempt in range(attempts):
if attempt == 0:
tempList = list(word[0] + ("." * 4))
print("The first letter of the word we are looking for: %s" % "".join(tempList))
answer = raw_input("What is the word we are looking for?:")
if len(answer) != 5:
print ('Please enter a 5 letter word')
Else:
if answer != word:
wordlist = list(word)
answerlist = list(answer)
for i in range(min(len(wordlist), len(answerlist))):
if wordlist[i] == answerlist[i]:
tempList[i] = wordlist[i]
print(tempList)
else:
print("correct, you have guessed the word in:", attempt, "attempts")
if answer != word:
print("Sorry maximum number of tries, the word is: %s" % word)
I have two questions about this code:
The first one is a small problem: If the user gives a 6 or 4 letter word it will still print the word. While I'd rather have it that the word is just ignored and the attempt isnt used..
If a letter is given correct (and also the first letter) it doesnt become a standard part of the feedback. Trying to get this with temp but of yet its not working great.
Any suggestions to clean up my code are also appreciated!
Thanks for your attention
I made some changes in your code, now it's working according to your specification. I also wrote a couple of explaining comments in it:
import random
list_of_words = ["apple", "table", "words", "beers", "plural", "hands"]
word = random.choice(list_of_words)
# changed the loop to a 'while', because i don't want to count the invalid length answers
# and wanted to exit the loop, when the user guessed correctly
attempts = 5
attempt = 0
correct = False
while attempt < attempts and not correct:
if attempt == 0:
# i stored a working copy of the initial hint (ex: "w....")
# i'll use this to store the previously correctrly guessed letters
tempList = list(word[0] + ("." * 4))
print("The first letter of the word we are looking for: %s" % "".join(tempList))
answer = raw_input("What is the word we are looking for?:")
if len(answer) != 5:
print("Please enter a 5 letter word")
else:
if answer != word:
# i simplified this loop to comparing the wordlist and answerlist and update templist accordingly
wordlist = list(word)
answerlist = list(answer)
for i in range(min(len(wordlist), len(answerlist))):
if wordlist[i] == answerlist[i]:
tempList[i] = wordlist[i]
print(tempList)
else:
correct = True
print("Correct, you have guessed the word in %s attempts" % (attempt + 1))
attempt += 1
if answer != word:
# also i used string formatting on your prints, so is prints as a string, and not as a tuple.
print("Sorry maximum number of tries, the word is: %s" % word)
There are several problems with the code.
Just 1 for now. I notice in the sample output you are entering five letter words (beeds and bread) and it still prints out Please enter a 5 letter word.
These two lines:
if len(answer) != 4:
print ('Please enter a 5 letter word')
Surely this should be:
if len(answer) != 5:
print ('Please enter a 5 letter word')
continue
This would catch an invalid input and go round the loop again.
Answering your specific questions:
You will need to have a for loop around your input, keeping the user in that loop until they enter a word of appropriate length
If you move guessed letters to the correct places, it is trivial to win by guessing "abcde" then "fghij", etc. You need to think carefully about what your rules will be; you could have a separate list of "letters in the guess that are in the answer but in the wrong place" and show the user this.
To keep the display version with all previously-guessed characters, keep a list of the display characters: display = ["." for letter in answer], and update this as you go.
Other problems you have:
Too much hard-coding of word length (especially as len("plural") != 5); you should rewrite your code to use the length of the word (this makes it more flexible).
You only tell the user they've won if they guess the whole answer. What if they get to it with overlapping letters? You could test as if all(letter != "." for letter in display): to see if they have got to the answer that way.
Your list comprehension [i for i in answer if answer in word] is never assigned to anything.

Categories