I made a simple Hangman game in Python:
import random
class Hangman:
def __init__(self):
self.words = ["bike", "monkey", "planet"]
self.random_word = random.choice(self.words)
self.lenght = len(self.random_word)
self.no_of_try = int(self.lenght) + 3
self.empty_word = ["_"] * self.lenght
@staticmethod
def user_input():
print("Enter a guess: ")
user_input = input()
return user_input
def find_index(self):
letter = self.user_input()
possition = self.random_word.index(letter)
return (letter, possition)
def substitue(self):
try:
guess_letter, guess_index = self.find_index()
self.empty_word[guess_index] = guess_letter
print(self.empty_word)
return True
except ValueError as e:
return False
def play_game(self):
while self.no_of_try > 0:
print("no: " + str(self.no_of_try))
game = self.substitue()
if game:
print("Bravo")
self.no_of_try -= 1
else:
self.no_of_try -= 1
print("Wrong")
if "_" not in self.empty_word:
print("You win")
break
if self.no_of_try == 0:
print("Game over")
break
if __name__ == "__main__":
h = Hangman()
h.play_game()
1 Answer 1
Right now the program will have a problem if you use a word which has the same letter more than once. string.index will only return the index of the first occurrence. What you could do instead is use a set to check what letters still need to be guessed. If a character in the word is still in the set, it hasn’t been guessed and an underscore should be printed. If it isn’t in the set, it has been guessed and it should be printed.
The code can be simplified significantly. You only really need one function which takes a list of strings as an argument. You could do something like this:
import random
def hangman(word_list):
word = random.choice(word_list)
letters = set(word)
guesses = len(word) + 3
while len(letters) > 0 and guesses > 0:
guess = input(str(guesses) + " guesses left\nguess something:\n")
if guess in letters:
print("correct")
letters.remove(guess)
else:
print("wrong")
guesses -= 1
print(*(ch if ch not in letters else '_' for ch in word))
print("win" if len(letters) == 0 else "lose")
if __name__ == "__main__":
hangman(["bike", "monkey", "planet", "mississippi"])
NITPICKING
You have a function in your current code which could be replaced with a call to input. the user_input function could be replaced with this: input("Enter a guess:\n")
. Also you can simplify this:
if game:
print("Bravo")
self.no_of_try -= 1
else:
self.no_of_try -= 1
print("Wrong")
into this:
self.no_of_try -= 1
print("Bravo" if game else "Wrong")
I also noticed a couple things in the __init__ method. The word list and the randomly chosen word’s length don’t need to be instance variables because they’re only used in __init__, and you don’t need to cast the length to int because it’s already an int.
-
1\$\begingroup\$ Thank you. This was really helpful, I will consider this practices in the future projects :) \$\endgroup\$TheOriginalOdis– TheOriginalOdis2021年01月15日 09:33:56 +00:00Commented Jan 15, 2021 at 9:33