Skip to content

Commit 2a26772

Browse files
committed
add hangman game for Hacktober open source contribution
1 parent 9c0a8cd commit 2a26772

File tree

1 file changed

+166
-82
lines changed

1 file changed

+166
-82
lines changed

other/password.py

Lines changed: 166 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,180 @@
1-
import secrets
2-
from random import shuffle
3-
from string import ascii_letters, ascii_lowercase, ascii_uppercase, digits, punctuation
1+
"""
2+
hangman.py
3+
A simple command-line Hangman game implemented in Python.
4+
5+
This program randomly selects a word from a given list and allows the user
6+
to guess it letter by letter. The game ends when the user either correctly
7+
guesses all the letters or exceeds the maximum allowed wrong attempts.
8+
9+
Usage:
10+
python hangman.py
11+
12+
Example:
13+
$ python hangman.py
14+
Welcome to Hangman!
15+
_ _ _ _ _
16+
Enter a letter: a
17+
Correct!
18+
a _ _ _ _
19+
...
20+
"""
21+
22+
import random
23+
24+
# ----------------------------- #
25+
# HANGMAN STAGES
26+
# ----------------------------- #
27+
28+
words = (
29+
# Fruits
30+
'apple', 'orange', 'banana', 'coconut', 'pineapple', 'mango', 'papaya',
31+
'strawberry', 'blueberry', 'raspberry', 'grape', 'watermelon', 'peach',
32+
'pear', 'cherry', 'plum', 'kiwi', 'apricot', 'lemon', 'lime',
33+
34+
# Animals
35+
'elephant', 'tiger', 'lion', 'giraffe', 'zebra', 'monkey', 'kangaroo',
36+
'dolphin', 'rabbit', 'panda', 'koala', 'wolf', 'bear', 'fox', 'camel',
37+
'penguin', 'snake', 'turtle', 'deer', 'leopard',
38+
39+
# Countries
40+
'pakistan', 'india', 'china', 'japan', 'brazil', 'canada', 'france',
41+
'germany', 'australia', 'italy', 'spain', 'egypt', 'turkey', 'russia',
42+
'mexico', 'norway', 'sweden', 'argentina', 'indonesia', 'nigeria',
43+
44+
# Colors
45+
'red', 'blue', 'green', 'yellow', 'purple', 'orange', 'black', 'white',
46+
'pink', 'brown', 'gray', 'violet', 'indigo', 'silver', 'gold',
47+
48+
# Computer / Tech
49+
'python', 'javascript', 'variable', 'function', 'developer', 'keyboard',
50+
'internet', 'website', 'database', 'algorithm', 'software', 'hardware',
51+
'network', 'browser', 'program', 'compiler', 'laptop', 'machine', 'coding',
52+
53+
# Random everyday words
54+
'school', 'teacher', 'window', 'garden', 'flower', 'butterfly', 'dream',
55+
'sunshine', 'moonlight', 'family', 'holiday', 'mountain', 'river',
56+
'forest', 'island', 'cloud', 'ocean', 'rainbow', 'friend', 'love'
57+
)
58+
59+
hangman_art: dict[int, tuple[str, str, str]] = {
60+
0: (" ", " ", " "),
61+
1: (" o ", " ", " "),
62+
2: (" o ", " | ", " "),
63+
3: (" o ", "/| ", " "),
64+
4: (" o ", "/|\\ ", " "),
65+
5: (" o ", "/|\\ ", "/ "),
66+
6: (" o ", "/|\\ ", "/ \\ "),
67+
}
68+
69+
70+
def display_man(wrong_guesses: int) -> None:
71+
"""
72+
Display the current hangman stage according to the number of wrong guesses.
73+
74+
Args:
75+
wrong_guesses (int): Number of incorrect guesses made so far.
76+
77+
>>> display_man(0)
78+
*****************
79+
80+
481
82+
*****************
83+
>>> display_man(1)
84+
*****************
85+
o
86+
87+
588
6-
def password_generator(length: int = 8) -> str:
89+
*****************
790
"""
8-
Password Generator allows you to generate a random password of length N.
9-
10-
>>> len(password_generator())
11-
8
12-
>>> len(password_generator(length=16))
13-
16
14-
>>> len(password_generator(257))
15-
257
16-
>>> len(password_generator(length=0))
17-
0
18-
>>> len(password_generator(-1))
19-
0
91+
print("*****************")
92+
for line in hangman_art[wrong_guesses]:
93+
print(line)
94+
print("*****************")
95+
96+
97+
def display_hint(hint: list[str]) -> None:
2098
"""
21-
chars = ascii_letters + digits + punctuation
22-
return "".join(secrets.choice(chars) for _ in range(length))
23-
24-
25-
# ALTERNATIVE METHODS
26-
# chars_incl= characters that must be in password
27-
# i= how many letters or characters the password length will be
28-
def alternative_password_generator(chars_incl: str, i: int) -> str:
29-
# Password Generator = full boot with random_number, random_letters, and
30-
# random_character FUNCTIONS
31-
# Put your code here...
32-
i -= len(chars_incl)
33-
quotient = i // 3
34-
remainder = i % 3
35-
# chars = chars_incl + random_letters(ascii_letters, i / 3 + remainder) +
36-
# random_number(digits, i / 3) + random_characters(punctuation, i / 3)
37-
chars = (
38-
chars_incl
39-
+ random(ascii_letters, quotient + remainder)
40-
+ random(digits, quotient)
41-
+ random(punctuation, quotient)
42-
)
43-
list_of_chars = list(chars)
44-
shuffle(list_of_chars)
45-
return "".join(list_of_chars)
46-
47-
# random is a generalised function for letters, characters and numbers
48-
49-
50-
def random(chars_incl: str, i: int) -> str:
51-
return "".join(secrets.choice(chars_incl) for _ in range(i))
52-
53-
54-
def is_strong_password(password: str, min_length: int = 8) -> bool:
99+
Display the current state of the guessed word as underscores and letters.
100+
101+
Args:
102+
hint (list[str]): List containing correctly guessed letters or underscores.
103+
104+
>>> display_hint(['a', '_', 'p', '_', 'e'])
105+
a _ p _ e
55106
"""
56-
This will check whether a given password is strong or not. The password must be at
57-
least as long as the provided minimum length, and it must contain at least 1
58-
lowercase letter, 1 uppercase letter, 1 number and 1 special character.
59-
60-
>>> is_strong_password('Hwea7$2!')
61-
True
62-
>>> is_strong_password('Sh0r1')
63-
False
64-
>>> is_strong_password('Hello123')
65-
False
66-
>>> is_strong_password('Hello1238udfhiaf038fajdvjjf!jaiuFhkqi1')
67-
True
68-
>>> is_strong_password('0')
69-
False
107+
print(" ".join(hint))
108+
109+
110+
def display_answer(answer: str) -> None:
70111
"""
112+
Display the correct word at the end of the game.
71113
72-
if len(password) < min_length:
73-
return False
114+
Args:
115+
answer (str): The correct word that was to be guessed.
74116
75-
upper = any(char in ascii_uppercase for char in password)
76-
lower = any(char in ascii_lowercase for char in password)
77-
num = any(char in digits for char in password)
78-
spec_char = any(char in punctuation for char in password)
117+
>>> display_answer('python')
118+
The correct word was: python
119+
"""
120+
print(f"The correct word was: {answer}")
79121

80-
return upper and lower and num and spec_char
81122

123+
def main() -> None:
124+
"""
125+
Main function to run the Hangman game.
82126
83-
def main():
84-
length = int(input("Please indicate the max length of your password: ").strip())
85-
chars_incl = input(
86-
"Please indicate the characters that must be in your password: "
87-
).strip()
88-
print("Password generated:", password_generator(length))
89-
print(
90-
"Alternative Password generated:",
91-
alternative_password_generator(chars_incl, length),
92-
)
93-
print("[If you are thinking of using this password, You better save it.]")
127+
The player has up to 6 incorrect guesses to complete the word.
128+
The game ends when the player wins or loses.
129+
"""
130+
answer: str = random.choice(words)
131+
hint: list[str] = ["_"] * len(answer)
132+
wrong_guesses: int = 0
133+
guessed_letters: set[str] = set()
134+
is_running: bool = True
135+
136+
print("\n Welcome to Hangman!")
137+
print("Guess the word, one letter at a time.\n")
138+
139+
while is_running:
140+
display_man(wrong_guesses)
141+
display_hint(hint)
142+
guess = input("Enter a letter: ").lower().strip()
143+
144+
# Input validation
145+
if len(guess) != 1 or not guess.isalpha():
146+
print("Invalid input. Please enter a single alphabetic character.\n")
147+
continue
148+
149+
if guess in guessed_letters:
150+
print(f"'{guess}' has already been guessed.\n")
151+
continue
152+
153+
guessed_letters.add(guess)
154+
155+
# Check if the guessed letter is in the word
156+
if guess in answer:
157+
for i, letter in enumerate(answer):
158+
if letter == guess:
159+
hint[i] = guess
160+
print("Correct!\n")
161+
else:
162+
wrong_guesses += 1
163+
print("Wrong guess!\n")
164+
165+
# Win condition
166+
if "_" not in hint:
167+
display_man(wrong_guesses)
168+
display_answer(answer)
169+
print("YOU WIN!\n")
170+
is_running = False
171+
172+
# Lose condition
173+
elif wrong_guesses >= len(hangman_art) - 1:
174+
display_man(wrong_guesses)
175+
display_answer(answer)
176+
print("YOU LOSE!\n")
177+
is_running = False
94178

95179

96180
if __name__ == "__main__":

0 commit comments

Comments
 (0)