3
\$\begingroup\$

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()
Toby Speight
87.3k14 gold badges104 silver badges322 bronze badges
asked Jan 14, 2021 at 21:26
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

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.

answered Jan 14, 2021 at 23:30
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thank you. This was really helpful, I will consider this practices in the future projects :) \$\endgroup\$ Commented Jan 15, 2021 at 9:33

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.