How to make a hangman remember your guesses in Python? - python

This is currently what I have written:
That is a Hangman Game. After guessing the letter, code should remember previous guess. But it does not.
What changes should I make for this code?
import random
word_list = ["aardvark", "baboon", "camel"]
chosen_word = random.choice(word_list)
print(f'Pssst, the solution is {chosen_word}.')
display = []
for i in range(0, len(chosen_word)):
display.append("_")
listToStr = ' '.join(display)
print(listToStr)
end = False
while not end:
guess = input("Guess a letter: ").lower()
result = []
for letter in chosen_word:
if letter == guess:
result.append(guess)
else:
result.append(display[i])
result = ' '.join(result)
print(result)
if "_" not in display:
end = True

In your while loop the result array is initialized every iteration.
This means the result is cleared every loop and only the last guess is added to the new empty result array.

Related

hangman from 100 days of python solution

Is there a way to insert letters in a specific place where they (letters) are located inside a word?
This code allows me to do so, but adds '_' at the end of a list and misses the spot for a second letter if there are multiples of the same in one word. For example - pumpkin, it would add the first 'p' at its rightful place, but the second one will be right after.
These are my instructions:
Use a while loop to let the user guess again. The loop should only stop once the user has guessed all the letters in the chosen_word and 'display' has no more blanks ("_"). Then you can tell the user they've won.
import random
word_list = ["aardvark", "baboon", "camel"]
chosen_word = random.choice(word_list)
guess = input("Guess a letter: ").lower()
display = []
for i in chosen_word:
if i ==guess:
display.append(i)
else:
display.append('_')
print(display)
while '_' in display:
guess = input("Guess a letter: ").lower()
for i in chosen_word:
if i ==guess:
display.insert(chosen_word.index(i),i)
print(display)
.index(char) always gives first position.
You would have to use .index(char, start_position) to search after first position
pos = chosen_word.index(char) # first position
display.insert(pos, char)
pos = chosen_word.index(char, pos+1) # second position
display.insert(pos, char)
# etc.
You could try to do it in loop - and start with pos = -1
pos = -1
for ...:
if ...:
pos = chosen_word.index(char, pos+1)
display[pos] = char
but it can be simpler to use
for index, char in enumerate(chosen_word):
if char == guess:
display[index] = char
import random
word_list = ["pumpkin", "aardvark", "baboon", "camel"]
chosen_word = random.choice(word_list)
display = ['_'] * len(chosen_word)
print("".join(display))
while '_' in display:
guess = input("Guess a letter: ")
for index, char in enumerate(chosen_word):
if char.lower() == guess.lower():
display[index] = char
print("".join(display))

How to a terminate a while loop?

I have this code that defines a word and I am making guesses of letters that form the actual word. It works perfectly, but I am unable to terminate the loop from taking in user input after I obtain the correct formation of letters. Does any one have an idea in terminating the loop?
word = "EVAPORATE"
guessed_word = "_" * len(word)
word = list(word)
guessed_word = list(guessed_word)
new_list = []
while True:
guess_letter = input("Enter a guess: ")
for index, letter in enumerate(word):
if letter == guess_letter:
guessed_word[index] = letter
print(' '.join(guessed_word))
You can simply change while True to while word != guessed_word, then it will stop after you obtain the correct answer.
This will work
word = "EVAPORATE"
word = word.lower()
word = list(word)
guessed_word = "_" * len(word)
guessed_word = list(guessed_word)
new_list = []
while True:
guess_letter = input("Enter a guess: ")
for index, letter in enumerate(word):
if letter == guess_letter:
guessed_word[index] = letter
print(' '.join(guessed_word))
if '_' not in guessed_word:
print('Congratulation!')
break
you should get to know about flow control statements being break, continue and pass. Look at break for this particular question
You can use break.
For example...
n = 5
while n > 0:
n -= 1
if n == 2:
break
print(n)
print('Loop ended.')

Improve the odds of winning at hangman with ai

I'm new (and to stack overflow, this is the first question I have ever asked) to python, I have been self-teaching myself for a couple of weeks. I was doing some beginner projects when I decided to make a hangman ai.
#importing
import random
import time
import sys
from collections import Counter
#---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#defining some variables
list_of_words = open("dictionary.txt", "r")
list_of_words = list_of_words.read().split()
SYMBOL = "abcdefghijklmnopqrstuvwxyz"
#---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#main game loop
def main():
while True:
print("\nGenerating word...")
word = list_of_words[random.randint(0, len(list_of_words) - 1)].lower()
word_guess = []
wrong_attempts = 0
wrong_letters = []
game_state = True
for symbol in word:
if symbol in SYMBOL:
word_guess.append("_")
else:
word_guess.append(symbol)
word_show = " ".join(word_guess)
word = list(word)
while game_state != False:
print("\n" + word_show)
print("\nWrong attempts [{0}/5]" .format(wrong_attempts))
if len(wrong_letters) > 0:
print("\nLetters guessed [{0}]" .format(", ".join(wrong_letters)))
letter = "-"
while letter not in SYMBOL or letter == "" or len(letter) > 1:
try:
letter = input("\nGuess a letter or enter 0 to call the ai: ")
except:
print("\nUnexpected error ocurred, try again")
if letter == "0":
correct_letters = [letter for letter in word_guess if letter in SYMBOL]
letter = ai_solver(wrong_letters, word_guess)
elif letter in wrong_letters or letter in word_guess:
print("\nYou already guessed letter [{0}]" .format(letter))
letter = ""
if letter in word:
for i in range(len(word)):
if letter == word[i]:
word_guess[i] = letter
else:
wrong_letters.append(letter)
wrong_attempts += 1
word_show = " ".join(word_guess)
if "".join(word_guess) == "".join(word):
print("\nYou won!")
game_state = False
elif wrong_attempts == 5:
print("\nYou lost!")
print("The word was [{0}]" .format("".join(word)))
game_state = False
option = input("\nWant to play again?[Y/N]: ")
if option.lower().startswith("n"):
sys.exit(0)
def ai_solver(letters_attempted, word_guess):
letters_attempted = letters_attempted if len(letters_attempted) != 0 else ""
available_words = []
for word in list_of_words:
append = False
if len(word) == len(word_guess):
append = True
for i in range(len(word_guess)):
if word[i] in letters_attempted:
append = False
break
if word_guess[i] != "_":
if word[i] != word_guess[i]:
append = False
break
if append == True:
print("[{0}]" .format(word))
available_words.append(word)
common_letters = [letter for letter in "".join(available_words) if letter not in word_guess]
common_letters = Counter("".join(common_letters)).most_common(1)
return common_letters[0][0]
main()
What I tried to do is, to filter all the possible words that have the same length as word_guess.
Then filter out any words that contained a letter that was guessed incorrectly by checking letters_attempted.
Then it would filter out all words that had letters that did not match with word_guess.
if word_guess[i] != "_":
if word[i] != word_guess[i]:
append = False
break
Although it works fine, sometimes it would lose, what can I add to increase the chances of winning?
Thank you!
Your two filter steps are a good first start. There are several different steps you could take to try to improve things. Let's call the words that fit the criteria so far the candidate words.
The first step would be to analyze all the candidate words and figure out which letter appears most frequently in the candidate words. (Not counting repeated letters multiple times.) That letter would make a good next guess.
A slightly more sophisticated approach would look at information gain from a guess. That is, it might be that half the candidate words have a 's', but all such words end in 's'. There might be slight fewer candidate words with a 't', but the 't' can appear anywhere in the word. So, when you guess 't' you actually get a lot more information about what the word could be, because you are shown the location of the 't' when you guess it correctly. Particularly when you don't have enough guesses to figure out every word, such a strategy may help you figure out more words in the guesses that you have.

Saving results of loop iterations in a game

I am trying to make a hangman game and I am running into trouble with the display. I have a loop that is supposed to put the correctly guessed letters in the right places, however it only shows the correct location for one letter at a time. I thought it would be helpful to save the result of the previous iteration, and then display that, but I am not sure how to do that.
import random,time
hanglist = []
answerlist = []
file_var = open("wordlist.100000")
for n in file_var:
hanglist.append(file_var.readline())
word = random.choice(hanglist)
print("word is",word)
guesses = 10
while guesses != 0:
print("guess a letter")
answer = input()
answerlist.append(answer)
if answer in word:
m = list(word)
for n in m:
if n == answer:
print(answer, end = '')
else:
print('_', end = '')
else:
print("close, but not exactly")
guesses -= 1
And here are the outputs
word is fabric
guess a letter
f
f______guess a letter
a
_a_____guess a letter
To solve your issue just replace if n==answer to if n in answer. But, from the above code, I can see code can't handle these issues:
If the user guesses the same word again and again
After 4 guesses are done and total word is guessed, then code should break out of the loop, which it is not happening.
While reading line, it need to strip the '\n' otherwise its really hard
My code addresses these issue:
import random,time
hanglist = []
answerlist = []
file_var = open("wordlist.100000")
for n in file_var:
# strips the '/n' at the end
hanglist.append(file_var.readline().rstrip())
word = random.choice(hanglist)
print("word is",word)
guesses = 10
while guesses!=0:
print("guess a letter")
answer = input()
if answer in answerlist:
continue
answerlist.append(answer)
if answer in word:
# to print entire word guessed till now- with current and previous iterations
word_print = ''
for n in word:
# to print all the last state occurences
if n in answerlist:
word_print += n
else:
word_print += '_'
print(word_print,end='')
# word is correctly guessed
if '_' not in word_print:
break
else:
print("close, but not exactly")
guesses = guesses-1
Your issue is with
if n == answer:
print(answer,end = '')
else:
print('_', end = '')
which only compares each letter with the current guess, answer. Instead, if you use
if n in answerlist:
print(n, end = '')
else:
print('_', end = '')
it will show the letter if that letter is in the list of their previous guesses.
Additionally: the previous m= list(word) is not necessary, as for n in word: is valid.

Cannot get simple while loop working in Python

LETTERS = "abc"
correct = "cab "
guess = ""
while guess != correct:
for i in LETTERS:
position = random.randrange(len(LETTERS))
guess += LETTERS[position]
LETTERS = LETTERS[:position] + LETTERS[(position + 1):]
print(guess)
I'm new in Python and I want to make this simple program:
With the letters "abc", jumble them and create a new three-lettter word randomly.
Print that jumble
Continue doing this loop until the computer jumbles "cab".
Then stop.
I came up with this code, and it gives me an infinite loop. I can't figure out why is doing it. I'm sure it's something easy but I can't see it. Need some help! Thanks!
You have three problems that I can see:
"cab " has a space in it, and LETTERS does not have a space. So you'll never be able to guess a space
You don't reset guess. You simply keep adding to it
You change LETTERS in your for-loop, so in the second iteration of your while-loop, it will be completely empty.
This is how I would go about doing what you're trying to do (with minimal modification):
_LETTERS = "abc"
correct = "cab"
guess = ""
while guess != correct:
LETTERS = _LETTERS[:]
guess = ""
for i in LETTERS:
position = random.randrange(len(LETTERS))
guess += LETTERS[position]
LETTERS = LETTERS[:position] + LETTERS[(position + 1):]
print(guess)
Here's how I would do a random search (which is what you're trying to do):
guess = "abc"
correct = "cab"
while guess != correct:
guess = list(guess)
random.shuffle(guess)
guess = ''.join(guess)
print(guess)
print(guess)
Of course, there are better techniques to correctly guess "cab". If you really want to try an exhaustive search, then you could use a backtracking DFS:
def DFS(letters, correct, sofar=None)
if sofar is None:
sofar = ''
if not letters:
if sofar == correct:
print("Yay! I found it")
else:
print("Oops! I found %s instead" %sofar)
else:
for i,char in enumerate(letters):
DFS(letters[:i]+letters[i+1:], correct, sofar+char)
Your correct value contains a space, but your loop never generates spaces:
correct = "cab "
Remove that space:
correct = "cab"
Next, your loop reduces LETTERS to an empty string, so only once does your loop produce a random guess, but afterwards, you forever are stuck with LETTERS = '', so no for loop is run.
You'd be better off using random.shuffle to produce guesses:
LETTERS = list("abc")
correct = "cab"
while True:
random.shuffle(LETTERS)
guess = ''.join(LETTERS)
if guess == correct:
print(guess)
break

Categories