From be11f63435255e7aa86828c4897bf20524f7baec Mon Sep 17 00:00:00 2001 From: blais3pasc4l Date: Tue, 23 Nov 2021 01:54:40 -0500 Subject: [PATCH] gamer python check --- projects/game_Hangman/archivos/data.txt | 171 ++++++++++++ projects/game_Hangman/game_Hangman_game.py | 300 +++++++++++++++++++++ 2 files changed, 471 insertions(+) create mode 100644 projects/game_Hangman/archivos/data.txt create mode 100644 projects/game_Hangman/game_Hangman_game.py diff --git a/projects/game_Hangman/archivos/data.txt b/projects/game_Hangman/archivos/data.txt new file mode 100644 index 00000000..27fda38f --- /dev/null +++ b/projects/game_Hangman/archivos/data.txt @@ -0,0 +1,171 @@ +cream +coffee shop +star +explosion +guitar +plastic +razor +hammer +books +pencil +pen +aluminum +boat +lyrics +lace +window +library +sound +University +wheel +dog +keys +shirt +hair +dad +armchair +happiness +cot +keyboard +napkin +school +screen +Sun +elbow +fork +statistics +Map +Water +message +lime +coherent +King +edifice +grass +presidency +leaves +talking +school +hail +tab +lamp +hand +monitor +flower +music +man +screw +room +sailboat +Grandma +grandfather +stick +satelite +temple +glasses +ballpoint +Plato +cloud +government +bottle +Castle +dwarf +home +book +person +planet +TV +gloves +metal +telephone +projector +infectious mononucleosis +T-shirt +tooth +Petroleum +hanger +auction +debate +ring +notebook +noise +Wall +drill +tool +letters +chocolate +glasses +printing machine +candies +living +lights +anguish +shoe +bomb +rain +eye +tie +Newspaper +tooth +plant +lollipop +Diver +office +blind +door +uncle +chair +salad +Meadow +Zoo +candidate +sport +container +diaries +Photography +Ave +iron +refuge +pants +boat +meat +snow +key +humidity +gun +Department +mobile +sadness +hippopotamus +sofa +bed +tree +allowance +jacket +speech +car +belt +arugula +famous +wood +lentils +flat +briefcase +watch +deputy +knife +deodorant +padlock +light +moutains +computer +radio +infectious mononucleosis +picture +hot +match +theater +steak +party +bullet +headphones \ No newline at end of file diff --git a/projects/game_Hangman/game_Hangman_game.py b/projects/game_Hangman/game_Hangman_game.py new file mode 100644 index 00000000..f04a77b9 --- /dev/null +++ b/projects/game_Hangman/game_Hangman_game.py @@ -0,0 +1,300 @@ +"""Hangman CLI game +Author: Jose Noriega +""" + +import os +import random +import unicodedata + +def clear(): + os.system('clear') + + +class GameManager: + """Holds all the business layer to make de game.""" + + def __init__(self): + self.strikes = 0 + self.words = [] + + self.word_indexes_used = [] + self.word = None + self.guessed_letters = None + + self._load_words() + self._set_game_level() + self._render_frame() + + def _render_frame(self): + """Renders and refresh the main scene.""" + + while True: + clear() + + self._render_level() + self._render_gallow() + self._render_word_indicator() + + if self.strikes >= 6: + print('=========== GAME OVER ===========') + print(f'WORD: {self.word}') + input('') + self.strikes = 0 + self.word_indexes_used = [] + self._set_game_level() + continue + + if len([letter for letter in self.word if letter not in self.guessed_letters]) == 0: + self._set_game_level() + input('') + continue + + letter = self._ask_for_letter() + if letter: + is_valid = self._validate_letter(letter) + if not is_valid: + self.strikes += 1 + + def _render_level(self): + """Shows the current level on the scene.""" + print('=' * 15 + f' LEVEL {len(self.word_indexes_used)} ' + '=' * 15) + + def _set_game_level(self): + """Sets the word to start the game.""" + self.guessed_letters = set() + idx = None + + while idx is None: + random_index = random.randint(0, len(self.words) - 1) + if random_index not in self.word_indexes_used: + idx = random_index + + self.word = self.words[idx] + self.word_indexes_used.append(idx) + + @staticmethod + def _normalize_string(string): + """Removes the accents from the provided string. + + Args: + string: String to be normalized + + Returns: + str: normalized string + """ + assert isinstance(string, str), 'The parameter should be a string.' + + return unicodedata.normalize('NFKD', string).encode('ASCII', 'ignore').decode() + + def _validate_letter(self, letter): + """Checks if the provided letter is part of the current word. + + Args: + letter: Letter typed by the user + Returns: + Bool: Validation result + """ + + assert isinstance(letter, str) and len(letter), 'letter should be a string' + + is_valid = False + + special_letters = ['Á', 'É', 'Í', 'Ó', 'Ú', 'Ü'] + + for char in self.word: + _char = char + _letter = letter + + if char in special_letters: + _char = self._normalize_string(char) + + if letter in special_letters: + _char = self._normalize_string(letter) + + if _char == _letter: + self.guessed_letters.add(char) + is_valid = True + + return is_valid + + def _load_words(self): + """Loads the words from a text file.""" + base_dir = os.path.dirname(os.path.realpath(__file__)) + + with open(os.path.join(base_dir, './archivos/data.txt'), 'r', encoding='UTF-8') as file: + for line in file: + normalized_word = line.strip().upper() + self.words.append(normalized_word) + + assert len(self.words) > 0, 'There are not words in the data file' + + def _render_word_indicator(self): + """Renders the word fields in the scene.""" + # normalized_word = unicodedata.normalize('NFKD', normalized_word).encode('ASCII', 'ignore') + + template = '' + + for letter in self.word: + if letter in list(self.guessed_letters): + template += f' {letter} ' + else: + template += f' __ ' + + print('Word: ', template) + + def _render_gallow(self): + """Renders the gallow scene based on the strikes. + + Strike description: + - For 0 it will render just the gallow + - For 1 it will render the head + - For 2 it will render the torso + - For 3 it will render the left arm + - For 4 it will render the right arm + - For 5 it will render the left leg + - For 6 it will render the right leg + """ + + template = """ +** ** *** ** ** ******* ** ** *** ** ** +** ** ** ** *** ** ** *** *** ** ** *** ** +****** ***** **** ** ** *** **** **** ***** **** ** +** ** ** ** ** **** ** ** ** **** ** ** ** ** **** +** ** ** ** ** *** ******* ** ** ** ** ** ** *** + ||=================== + || + || + || + || + || + || + || + || + || + || + || + ==========@ ======== + || || + || || + || || + """ + + head = ( + (8, 23, '|',), + (9, 23, '|',), + (10, 22, '_',), + (10, 23, '_',), + (10, 24, '_',), + (11, 20, '|',), + (11, 22, '.',), + (11, 24, '.',), + (11, 26, '|',), + + (12, 21, '\\',), + (12, 23, '_',), + (12, 25, '/',), + ) + + torso = ( + (13, 23, '|',), + (13, 24, '|',), + (14, 23, '|',), + (14, 24, '|',), + (15, 23, '|',), + (15, 24, '|',), + (16, 23, '|',), + (16, 24, '|',), + ) + + left_arm = ( + (14, 20, '=',), + (14, 21, '=',), + (14, 22, '=',), + ) + right_arm = ( + (14, 25, '=',), + (14, 26, '=',), + (14, 27, '=',), + ) + + left_leg = ( + (17, 22, '/',), + (17, 23, '/',), + (18, 21, '/',), + (18, 22, '/',), + ) + right_leg = ( + (17, 24, '\\',), + (17, 25, '\\',), + (18, 25, '\\',), + (18, 26, '\\',), + ) + tramp_closed = ( + (19, 19, '=',), + (19, 20, '=',), + (19, 21, '=',), + (19, 22, '=',), + (19, 23, '=',), + (19, 24, '=',), + (19, 25, '=',), + (19, 26, '=',), + (19, 27, '=',), + ) + tramp_opened = ( + (19, 19, '\\',), + (19, 20, '\\',), + (20, 20, '\\',), + (20, 21, '\\',), + (21, 21, '\\',), + (21, 22, '\\',), + (22, 22, '\\',), + (22, 23, '\\',), + ) + + scene_descriptors = [] + + if self.strikes >= 1: + scene_descriptors += head + if self.strikes >= 2: + scene_descriptors += torso + if self.strikes >= 3: + scene_descriptors += left_arm + if self.strikes >= 4: + scene_descriptors += right_arm + if self.strikes >= 5: + scene_descriptors += left_leg + if self.strikes == 6: + scene_descriptors += right_leg + + if self.strikes < 6: + scene_descriptors += tramp_closed + else: + scene_descriptors += tramp_opened + + lines = [list(line) for line in template.splitlines()] + + for descriptor in scene_descriptors: + lines[descriptor[0]][descriptor[1]] = descriptor[2] + + scene = '\n'.join([''.join(l) for l in lines]) + print(scene) + + def _ask_for_letter(self): + """Shows a form to enter the letter. + + + Returns: + str: returns the letter enterd by the user if is valid, otherwise, it will return None. + """ + + print('Instructions: Type a letter and press enter.') + input_letter = input(': ') + + if len(input_letter) != 1: + print('Input error: Please type a letter.') + input('') + return None + return input_letter.upper() + +if __name__ == '__main__': + game = GameManager() \ No newline at end of file