Skip to content

Instantly share code, notes, and snippets.

@sometowngeek

sometowngeek/board.py

Last active Feb 24, 2018
Embed
What would you like to do?
More OOP-like version of Hangman
from random import choice
class board:
_HANGMAN = (
"""
------
| |
|
|
|
|
|
|
|
----------
""",
"""
------
| |
| O
|
|
|
|
|
|
----------
""",
"""
------
| |
| O
| -+-
|
|
|
|
|
----------
""",
"""
------
| |
| O
| /-+-
|
|
|
|
|
----------
""",
"""
------
| |
| O
| /-+-/
|
|
|
|
|
----------
""",
"""
------
| |
| O
| /-+-/
| |
|
|
|
|
----------
""",
"""
------
| |
| O
| /-+-/
| |
| |
| |
| |
|
----------
""",
"""
------
| |
| O
| /-+-/
| |
| |
| | |
| | |
|
----------
""")
def __init__(self, *words):
self._used = []
self._wrong_answers = 0
self._words = [word for word in words]
self._word = choice(self._words)
self._so_far = "".join(["-" if c.isalpha() else " " for c in self._word])
# This method is **NOT** part of OOP
# because it doesn't deal with logic.
def add_to_used_letters(self, guess):
self._used.append(guess)
# This method is OOP
# because it deals with logic
def check_answer(self, guess):
"""
Checks to see if the user's guess is correct.
:param guess: User's guess
"""
if guess in self._word:
position = self._word.find(guess, 0)
while position >= 0:
self._so_far = self._so_far[:position] + guess + self._so_far[position+1:]
position = self._word.find(guess, position + 1)
return True
# If the guessed letter is not in the word:
self._wrong_answers += 1
return False
# OOP method
# because it deals with logic
def exists_in_used_letters(self, guess):
return guess in self._used # Does the guessed letter exist in used letters?
# OOP method
# because it deals with logic
def in_progress(self):
if self._wrong_answers == len(self._HANGMAN) or self._so_far == self._word:
return False
return True
# OOP method
# because it deals with logic
def game_won(self):
if self._wrong_answers == len(self._HANGMAN):
return False
return True
# This method is **NOT** part of OOP
# because it doesn't deal with logic.
def print_current_progress(self):
"""
Prints the current progress of the game.
"""
print()
print(self._HANGMAN[self._wrong_answers])
print("Word so far: ", self._so_far)
print("Letters used: ", sorted(self._used))
# Whenever possible, only import specific functions from the library
from random import choice
from time import sleep
from board import board
class Hangman:
"""
A Hangman class.
"""
_POSITIVE_SAYINGS = ("Well done!", "Awesome!", "You Legend!")
def __init__(self):
"""
The Python constructor for this class.
"""
self._board = board("APPLE", "ORACLE", "MIMO", "TESLA")
def play(self):
"""
This is the main driver of the game.
Plays the game.
"""
self._reset_game()
self._start_game()
# The amount of incorrect answers should be no greater than the length
# of HANGMAN.
#
# Use the length of HANGMAN to ensure there's no index
# overflow error when printing result.
while self._board.in_progress():
self._print_current_progress()
guess = self._user_guess()
self._check_result(guess)
self._wait()
self._print_result()
self._play_again()
# ---------------------------------
# "Private" methods
def _check_result(self, guess):
"""
Checks to see if the user's guess is correct.
:param guess: User's guess
"""
if self._board.check_answer(guess):
print(choice(self._POSITIVE_SAYINGS), "...Updating word so far...")
else:
print("INCORRECT! Try again!")
def _play_again(self):
"""
Asks the user if he or she would like to play again.
If the user wants to play again, calls play().
Otherwise, thanks the user for playing.
"""
print("Would you like to play again?")
if input("Enter Y for yes or N for no: ").upper() == "Y":
self.play()
else:
print()
print("Thank you for playing!")
def _print_current_progress(self):
"""
Prints the current progress of the game.
"""
self._board.print_current_progress()
def _print_result(self):
"""
Prints the result (win or lose).
"""
self._wait()
print("Calculating result...")
self._wait()
if self._board.game_won():
print("WINNER! Congratulations!")
else:
print("UNLUCKY! Better luck next time!")
def _reset_game(self):
"""
Resets the game by calling the constructor.
"""
self.__init__()
def _start_game(self):
"""
Starts the game by printing an introduction
and asks the user to hit the ENTER key to continue.
"""
print()
print("\t\tWelcome to Hangman!")
print()
input("Press Enter to START:")
def _user_guess(self):
"""
Asks for the user to guess a letter.
:returns: User's guessed letter.
"""
guess = input("Guess a letter: ").upper()
while self._board.exists_in_used_letters(guess):
self._wait()
print("Try again... You've already used this letter")
guess = input("Guess a letter: ").upper()
self._wait()
self._board.add_to_used_letters(guess)
return guess
def _wait(self):
sleep(1) # Time delay - allows user friendly reading
print()
if __name__ == '__main__':
game = Hangman()
game.play()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment