hangman from 100 days of python solution - python

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

Related

Trying to replace '_' with user input values, works fine except at index 0

import random
# making a list with word_list
word_list = ['Lemon', 'Apple', 'Kiwi']
#picking random word
chosen_word = random.choice(word_list)
print(f'the solution is {chosen_word}.')
display = []
word_length = len(chosen_word)
for _ in range(word_length):
display += '_'
print(display)
end_of_game = False
while not end_of_game:
guess = input('Guess the letter: ').lower()
for position in range(word_length):
letter = chosen_word[position]
if letter == guess:
display[position] = letter
print(display)
if '_' not in display:
end_of_game == True
print('You win')
For example, if chosen word is "Apple" and guess from user is 'A', it shows "A _ _ _ _". I need to fill all the spaces with correct letters, but what I am getting is all letters other than the letter at index 0.
You are using .lower() on the input given by the user, but the word that it is being compared with has an upper case letter at the start, hence letter = chosen_word[position] can never be True, for the first letter.
You can fix this by comparing the given input with the lowercase version of the chosen_word:
for position in range(word_length):
letter = chosen_word[position]
if letter.lower() == guess:
display[position] = letter
should work.

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.')

How to make a hangman remember your guesses in 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.

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.

Merging strings in python

I'm making a hangman game and I need to update the table showing the correct letters. So far the program prints this
Enter a word: hello
[-----] You have 6 guesses left, enter a letter: h
Correct!
[H----] You have 6 guesses left, enter a letter: e
Correct!
[-E---] You have 6 guesses left, enter a letter: l
Correct!
[--LL-] You have 6 guesses left, enter a letter: o
Correct!
[----O] You have 6 guesses left, enter a letter:
What I need the program to do is combine the strings for example [H----] --> [HE---] and so on. How would I do this? As well as end the game when there are no more dashes left.
An example of what I want the program to look like is
[H----]
[HE---]
the program also has to work in a random order for example...
[----O]
[-E--O]
[HE--O]
[HELLO]
This is my code so far
Just loop through the string to be guessed and show either the letter, if that letter was already guessed or '_' in case it hasn't.
In [127]: s = "Apple"
In [128]: already_guessed = ['p', 'e']
In [129]: '[' + ''.join([letter if letter in already_guessed else '_' for letter in s]) + ']'
Out[129]: '[_pp_e]'
Instead of recomputing display_string with "-", use the previous value of display_string. Note: You need to offset the index of display_string because of your brackets.
display_string = "[" + "".join([x if x == letter else display_string[i + 1] for i, x in enumerate(word)]) + "]"
Here's my attempt at an answer, wrote this up before you put up your code, so it may not be what you're looking for, but it works.
def hangman():
answer = raw_input('Enter a word: ') # getting the word
guesses = 6 # number of starting guesses
word = '[' + '-'*len(answer) + ']' # this is the string of interest to be printed
while True:
print word, 'You have %d guesses left' % guesses,
if guesses == 0 or '-' not in word: break
# game finishes if word is guessed, or guesses run out
letter = raw_input(', enter a letter: ') # guess a letter
guesses -= 1 # decrease number of guesses by 1 each time
for index, char in enumerate(answer): # iterate through all letters in answer
if letter == char: # check if guessed letter is in the answer
wordlist = list(word) # representing the word as a list to allow mutation
wordlist[index+1] = letter # mutate the correctly guessed letter
word = ''.join(wordlist) # recombining the list into a string

Categories