python improving word game - python

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.

Related

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

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/

Coding Hangman in 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.

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

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