Advertisement
Guest User

Hangman

a guest
Jan 8th, 2020
5,413
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.31 KB | None | 0 0
  1. from random import choice
  2. from bs4 import BeautifulSoup
  3. from string import ascii_letters
  4. import requests
  5.  
  6.  
  7. class Hangman:
  8.  
  9.     def __init__(self, *words):
  10.         """A text-based game of the all-time classic, Hangman. Can you save the man from the gallows?
  11.  
  12.        :param words:
  13.            Word(s) to be used for the game. String(s) can be passed directly as parameter(s) or in a list or
  14.            in a tuple. A word is chosen by random and assigned to 'self.word', which is then used for the
  15.            player to guess in a game of a hangman.
  16.        """
  17.         while isinstance(words, list) or isinstance(words, tuple):
  18.             words = choice(words)
  19.         if not isinstance(words, str):
  20.             raise TypeError(f"Expected 'str' type. Got {type(words)} instead.")
  21.         self.word = words.lower()
  22.         self.correct_guess = set(' ')
  23.         self.incorrect_guess = set()
  24.         self.attempts = 8
  25.         self.center = num if (calc := len(self.word) * 2 - 1) < (num := 15 + len(self.word)) else calc
  26.  
  27.     def play(self):
  28.         """Initiate a game of hangman.
  29.        """
  30.         self.draw_hangman()
  31.         while not set(self.word).issubset(self.correct_guess):
  32.             if (guess := self.get_letter()) in set(self.word):
  33.                 self.success_msg(guess)
  34.                 continue
  35.             self.failed_msg(guess)
  36.             if self.game_over():
  37.                 return
  38.         print(f"{'YOU WIN':^{self.center}}\n{'You guessed ' + self.word.upper():^{self.center}}\n")
  39.  
  40.     def get_letter(self):
  41.         """Return a single letter from the player's input. Also checks if the input is unique from previous inputs.
  42.        """
  43.         while True:
  44.             if len(guess := input('Enter a letter: ').lower()) > 1 or not guess.isalpha():
  45.                 print("Please enter one letter.")
  46.                 continue
  47.             if guess in self.correct_guess | self.incorrect_guess:
  48.                 print(f"You already entered '{guess}'. Please enter another letter.")
  49.                 continue
  50.             return guess
  51.  
  52.     def success_msg(self, guess):
  53.         """Display a success message along with the current progress of the game. Also updates set for correct guesses.
  54.        """
  55.         self.correct_guess.update(guess)
  56.         print(f"\n{'SUCCESS!':^{self.center}}")
  57.         self.draw_hangman()
  58.  
  59.     def failed_msg(self, guess):
  60.         """Display a failed message along with the current progress of the game. Also updates set for incorrect guesses
  61.        and subtracts one from attempts
  62.        """
  63.         self.attempts -= 1
  64.         self.incorrect_guess.update(guess)
  65.         print(f"\n{'FAILED!':^{self.center}}")
  66.         self.draw_hangman()
  67.  
  68.     def game_over(self):
  69.         """Returns a True if the user is out of attempts.
  70.        """
  71.         if self.attempts < 1:
  72.             print(f"{'GAME OVER':^{self.center}}\n{'The answer was ' + self.word.upper():^{self.center}}.\n")
  73.             self.attempts = 8
  74.             return True
  75.         return False
  76.  
  77.     def draw_hangman(self):
  78.         """Displays the number of attempts remaining and draws the hangman based on the attempts the player has left.
  79.        Also shows the player's progress on what letters they've guessed correctly.
  80.        """
  81.         print(f"{str(self.attempts) + ' Attempts left':^{self.center}}")
  82.  
  83.         # Displays hangman board when these strings are joined with a new line separator. i.e. '\n'.join(_hangman)
  84.         _hangman = ['  _____ ', '  |   | ', '      | ', '      | ', '      | ', '     _|_']
  85.  
  86.         # Modifies the hangman board based on player attempts.
  87.         if self.attempts < 8: _hangman[2] = _hangman[2][:2] + 'O'   + _hangman[2][3:]   # Draw head
  88.         if self.attempts < 7: _hangman[3] = _hangman[3][:1] + '/'   + _hangman[3][2:]   # Draw left arm
  89.         if self.attempts < 6: _hangman[3] = _hangman[3][:2] + '|'   + _hangman[3][3:]   # Draw torso
  90.         if self.attempts < 5: _hangman[3] = _hangman[3][:3] + '\\'  + _hangman[3][4:]   # Draw right arm
  91.         if self.attempts < 4: _hangman[4] = _hangman[4][:0] + '_'   + _hangman[4][1:]   # Draw left foot
  92.         if self.attempts < 3: _hangman[4] = _hangman[4][:1] + '/'   + _hangman[4][2:]   # Draw left leg
  93.         if self.attempts < 2: _hangman[4] = _hangman[4][:2] + "'\\" + _hangman[4][4:]   # Draw right leg
  94.         if self.attempts < 1: _hangman[4] = _hangman[4][:4] + '_'   + _hangman[4][5:]   # Draw right foot
  95.  
  96.         print(*[f"{section:^{self.center}}" for section in _hangman], sep='\n')
  97.         print(f"{' '.join([x.upper() if x in self.correct_guess else '_' for x in self.word]):^{self.center}}", '\n')
  98.  
  99.  
  100. class CommentGetter:
  101.  
  102.     def __init__(self):
  103.         """Module used for grabbing random comments from pornhub's comment section.
  104.        """
  105.         self.url = 'https://www.pornhub.com/'
  106.         data = requests.get(self.url)
  107.         self.soup = BeautifulSoup(data.text, 'lxml')
  108.  
  109.     def get_rand_video(self):
  110.         """Returns url of a random video from the hot section
  111.        """
  112.         hot_section = self.soup.find('ul', id='hotVideosSection')
  113.         return self.url[:-1] + choice([section.div.div.a['href'] for section in hot_section.find_all(
  114.             'li', class_='js-pop videoblock videoBox')])
  115.  
  116.     def get_rand_comment(self, url=None):
  117.         """Returns a random comment from a random video.
  118.        """
  119.         if url is None:
  120.             url = self.get_rand_video()
  121.         data = requests.get(url)
  122.         soup = BeautifulSoup(data.text, 'lxml')
  123.         comments = [comment.span.text for comment in soup.find_all('div', class_='commentMessage')]
  124.         while True:
  125.             if len(comment := ''.join([char for char in choice(comments) if char in ascii_letters + ' '])) > 1:
  126.                 return comment
  127.  
  128.  
  129. def ask_play():
  130.     """Ask the player if he/she would like to play.
  131.    """
  132.     while True:
  133.         if (play := input("Would you like to play Hangman? [Y/N]: ").lower()) in ['yes', 'y', '1']:
  134.             return True
  135.         if play in ['no', 'n', '2']:
  136.             raise SystemExit
  137.         print('Invalid input. Please try again.')
  138.  
  139.  
  140. def main():
  141.     while True:
  142.         if ask_play():
  143.             print('Fetching Comment...')
  144.             rand_comment = CommentGetter().get_rand_comment()
  145.             Hangman(rand_comment).play()
  146.  
  147.  
  148. if __name__ == '__main__':
  149.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement