def ship_hit(ai_game): """ Respond to the ship being hit by aliens """ logger.debug('Ship Hit') if ai_game.stats.ships_left > 0: # Decrement the ships left ai_game.stats.ships_left -= 1 # Update Scoreboard ai_game.scoreboard.prep_ships() # Empty the list of aliens and bullets ai_game.aliens.empty() ai_game.bullets.empty() # Create a new fleet and center the ship fleet_functions.create_fleet(ai_game) ai_game.ship.center_ship() # Pause sleep(.5) else: ai_game.stats.game_active = False pygame.mouse.set_visible(True)
def check_for_adjacent_type(dmap, pos_x, pos_y, tile_type): """ Checks whether there are any tile of specified type in adjucent tiles Returns: (bool) True if 1 or more specified type in adjucent tiles, False otherwise """ logger.debug("checking adjacent rooms of {},{} for {} tiles".format( pos_x, pos_y, tile_type)) is_adjacent = False for direction in directions.values(): x = pos_x + direction[0] y = pos_y + direction[1] if (x > 0 and y > 0 and x < len(dmap) and y < len(dmap[0]) and dmap[x][y] == map_generator.tiles[tile_type]): is_adjacent = True break logger.debug("adjacent rooms checked with result: {}".format(is_adjacent)) return is_adjacent
def is_position_in_map(dmap, pos_x, pos_y): """ Checks whether dungeon map has tile with specified coordinates. Args: dmap list of lists represanting dungeon map pos_x (int) x-coordinate of tile in question pos_y (int) y coordinate of tile in qustion Returns: (bool) True if dungeon map has tile with this coordinates, False otherwise """ logger.debug("is_position_in_map function invoked for position {}, {}".format(pos_x, pos_y)) map_height = len(dmap) map_width = len(dmap[0]) is_inside = (pos_x >= 0 and pos_y >= 0 and pos_x < map_width and pos_y < map_height) logger.debug("position {},{} checked. It's existance in map is {}".format(pos_x, pos_y, is_inside)) return is_inside
def init_game(): """ Initializes game, creating all needed variables. Returns: dmap - list of lists representing dungeon map discovered_map - parts of dungeon map discovered by player start_x (int) x-coordinate of player start position start_y (int) y-coordinate of player start position treasure_number (int) number of treasures in dungeon """ logger.debug("starting new game initialization") map_size = input_map_size() start_x = random.randint(0, map_size - 1) start_y = random.randint(0, map_size - 1) trap_number = map_size * map_size // 10 treasure_number = map_size * map_size // 20 dmap = map_generator.generate_dungeon_map(map_size, map_size, start_x, start_y, trap_number, treasure_number) discovered_map = [[ map_generator.tiles['unknown'] for i in range(map_size) ] for j in range(map_size)] return dmap, discovered_map, start_x, start_y, treasure_number
def update_screen(ai_game): """ Update images on the screen and flip to the new screen """ logger.debug('Updating Screen') # Redraw the screen ai_game.screen.fill(ai_game.settings.bg_color) # Redraw all bullets behind ship and aliens. for bullet in ai_game.bullets.sprites(): bullet.draw_bullet() # Redraw the ships' location ai_game.ship.blitme() ai_game.aliens.draw(ai_game.screen) # Draw the score info ai_game.scoreboard.show_score() # Draw the play button if the game is inactive if not ai_game.stats.game_active: ai_game.play_button.draw_button() # Make the most recently drawn screen visible pygame.display.flip()
def _write_move_fail_to_log(dir): """write fail while moving in specified directoin to log Arguments: dir str -- move direction """ logger.debug(F"failed to move {dir}")
def check_keyup_event(event, ai_game): """ Respond to key releases """ if event.key == pygame.K_RIGHT or event.key == pygame.K_d: logger.debug('Ship Right: Stop') ai_game.ship.moving_right = False elif event.key == pygame.K_LEFT or event.key == pygame.K_a: logger.debug('Ship Left: Stop') ai_game.ship.moving_left = False
def save_game(self): """ Saves current game. """ current_data = (DungeonGame.player, DungeonGame.dmap) save_file_name = "".join([DungeonGame.player.name, ".pickle"]) logger.debug("saving to {}".format(save_file_name)) with open(save_file_name, 'wb') as save_file: dump(current_data, save_file)
def prep_level(self): """ Turn the level in to a rendered image """ level_str = str(self.stats.level) logger.debug('LevelUp - New Level: {}'.format(self.stats.level)) self.level_image = self.font.render(level_str, True, self.text_color, self.ai_settings.bg_color) # Display the score at the upper left of the screen self.level_rect = self.level_image.get_rect() self.level_rect.right = self.screen_rect.right -20 self.level_rect.top = self.score_rect.bottom + 20
def get_number_of_rows(ai_settings, ship_height, alien_height): """ Determine the number of rows of aliens that fit on the screen """ available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height) logger.debug('Available Screen Y Space: {}'.format(available_space_y)) number_of_rows = int(available_space_y / (2 * alien_height)) logger.info('Number of Alien Rows: {}'.format(number_of_rows)) return number_of_rows
def save_game(self): """ Saves current game. """ hash = hashlib.md5(str(DungeonGame.player.name).encode()); current_data = (str(hash), DungeonGame.player, DungeonGame.enemy, DungeonGame.dmap) save_file_name = "".join([DungeonGame.player.name, ".pickle"]) logger.debug("saving to {}".format(save_file_name)) with open(save_file_name, 'wb') as save_file: dump(current_data, save_file)
def prep_score(self): """ Turn the score in to a rendered image """ rounded_score = int(round(self.stats.score, -1)) score_str = '{:,}'.format(rounded_score) logger.debug('Score Changed - New Score: {}'.format(self.stats.score)) self.score_image = self.font.render(score_str, True, self.text_color, self.ai_settings.bg_color) # Display the score at the upper left of the screen self.score_rect = self.score_image.get_rect() self.score_rect.right = self.screen_rect.right -20 self.score_rect.top = 20
def save_game(dmap, discovered_map, pos_x, pos_y, treasure_collected): """ Saves current game data. """ logger.debug("saving current game") current_data = (dmap, discovered_map, pos_x, pos_y, treasure_collected) with open(SAVE_FILE_NAME, 'wb') as dungeon_save_file: pickle.dump(current_data, dungeon_save_file) logger.debug("game is saved in{}".format(SAVE_FILE_NAME))
def get_number_aliens_x(ai_settings, alien_width): """ Determine the number of aliens that fit in a row """ # Create a border at both screen edges equal to the width of an alien available_space_x = ai_settings.screen_width - 2 * alien_width logger.debug('Available Screen X Space: {}'.format(available_space_x)) # Space between each alien is equal to the width of an alien number_aliens_x = int(available_space_x / (2 * alien_width)) logger.info('Number of Aliens per Row: {}'.format(number_aliens_x)) return number_aliens_x
def load_game(self): """ Loading game data from file. """ save_file_name = "".join([DungeonGame.player.name, ".pickle"]) logger.debug("loading from {}".format(save_file_name)) with open(save_file_name, 'rb') as save_file: game_data = load(save_file) DungeonGame.player, DungeonGame.dmap = game_data
def process_enemy_turn(self): """ Moves enemy to random ajucent cell """ new_position = DungeonGame.enemy.position + choice(DungeonGame.position_directions) while not self.dmap.is_position_in_map(new_position): new_position = DungeonGame.enemy.position + choice(DungeonGame.position_directions) DungeonGame.enemy.position = new_position logger.debug("enemy moves to {},{}".format(DungeonGame.enemy.position.x,\ DungeonGame.enemy.position.y))
def prep_high_score(self): """ Turn the high score in to a rendered image """ high_score = int(round(self.stats.high_score, -1)) high_score_str = '{:,}'.format(high_score) logger.debug('High Score Changed - New High Score: {}'.format(self.stats.score)) self.high_score_image = self.font.render(high_score_str, True, self.text_color, self.ai_settings.bg_color) # Display the score at the upper left of the screen self.high_score_rect = self.high_score_image.get_rect() self.high_score_rect.centerx = self.screen_rect.centerx self.high_score_rect.top = 20
def load_game(): """ Loading game data from file. """ logger.debug("loading game") with open(SAVE_FILE_NAME, 'rb') as dungeon_save_file: game_data = pickle.load(dungeon_save_file) logger.debug("game is loaded from{}".format(SAVE_FILE_NAME)) return game_data
def generate_dungeon_map(width, height, start_x, start_y, trap_number, treasure_number): """ Generates dungeon map Args: width (int) height (int) start_x(int) start_y(int) trap_number(int) number of traps on map treasure_number(int) number of treasures on map Returns: list of lists represanting map """ if trap_number + treasure_number > height * width: logger.debug("generate_dungeon_map has incorrect parameters") return dmap = [[tiles['empty'] for i in range(height)] for j in range(width)] dmap[start_x][start_y] = tiles['player'] logger.debug("generating {} traps".format(trap_number)) while trap_number > 0: x = randint(0, width - 1) y = randint(0, height - 1) if dmap[x][y] == tiles['empty']: dmap[x][y] = tiles['trap'] trap_number -= 1 logger.debug("traps generated") logger.debug("generating {} treasures".format(treasure_number)) while treasure_number > 0: x = randint(0, width - 1) y = randint(0, height - 1) if dmap[x][y] == tiles['empty']: dmap[x][y] = tiles['treasure'] treasure_number -= 1 logger.debug("treasures generated") return dmap
def print_dungeon_map(dungeon_map): """ Prints dungeon map """ printed_map = [[row[i] for row in dungeon_map] for i in range(len(dungeon_map[0]))] printed_map.reverse() for row in printed_map: for cell in row: print(str(cell), " ", end='') print('') logger.debug("map printed")
def respawn_enemy(self): """ Respawns enemy at random not occupied by Player cell. """ DungeonMap.enemy = choice(enemies_list) enemy_position = Position.generate_random_position(DungeonGame.dmap.width,\ DungeonGame.dmap.height) while enemy_position == DungeonGame.player.position: enemy_position = Position.generate_random_position(DungeonGame.dmap.width,\ DungeonGame.dmap.height) DungeonMap.enemy.position = enemy_position logger.debug("enemy spawned at {},{}".format(DungeonGame.enemy.position.x,\ DungeonGame.enemy.position.y))
def create_alien(ai_game, alien_number, row_number, col_number): """ Create and alien and place it in a row """ logger.debug('Alien {:3} - C: {:5} R: {:5} - Creating'.format( alien_number, col_number, row_number)) alien = Alien(ai_game.settings, ai_game.screen, alien_number) # Set alien's x & y coordinates alien.x = alien.rect.width + 2 * alien.rect.width * col_number alien.rect.x = alien.x alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number + 25 logger.debug(alien.debug_info('Starting Position')) # Add the new alien to the group of aliens ai_game.aliens.add(alien)
def count_tiles_of_type(dmap, tile_type): """ Counts tiles of specified type in dungeon map Args: dmap list of lists represanting dungeon map tile_type type of tiles in question Returns: (int) number of tiles of specified type in dungeon map """ logger.debug("generate_dungeon_map function invoked for type {}".format(tile_type)) number_of_tiles = 0 for column in dmap: number_of_tiles += column.count(tiles[tile_type]) return number_of_tiles
def check_bullet_alien_collisions(ai_game): # Check for any bullets that have hit aliens, if so get rid of the bullet and alien collisions = pygame.sprite.groupcollide(ai_game.bullets, ai_game.aliens, True, True) if collisions: for aliens in collisions.values(): ai_game.stats.score += ai_game.settings.alien_points * len(aliens) ai_game.scoreboard.prep_score() check_high_score(ai_game) # If fleet is 0 destroy existing bullets and create a new fleet if len(ai_game.aliens) == 0: logger.debug('Fleet Destroyed') ai_game.bullets.empty() ai_game.settings.increase_speed() fleet_functions.create_fleet(ai_game) # Increase the level ai_game.stats.level += 1 ai_game.scoreboard.prep_level()
def debug_wrapper(*args, **kwargs): if config.function_debug: bound_arguments = inspect.signature(func).bind(*args, **kwargs) bound_arguments.apply_defaults() debug_string = ["Calling {} with arguments:".format(func.__name__)] for key, value in bound_arguments.arguments.items(): debug_string.append("{} = {}".format(key, value)) debug_string = "\n".join(debug_string) logger.debug(debug_string) result = func(*args, **kwargs) logger.debug("{} returns {}".format(func.__name__, result)) else: result = func(*args, **kwargs) return result
def process_enemy(self): """ Process enemy turns, which are made in enemy_turn_time intervals. """ time_of_last_turn = time.time() while not self.is_game_ended(): if (DungeonGame.enemy.position == DungeonGame.player.position and not DungeonGame.is_room_being_processed): logger.debug("enemy finds player") DungeonGame.is_enemy_encounter_being_processed = True self.process_hostile_encounter(DungeonGame.enemy) DungeonGame.is_enemy_encounter_being_processed = False self.respawn_enemy() current_time = time.time() if current_time - time_of_last_turn > DungeonGame.enemy_turn_time: self.process_enemy_turn() time_of_last_turn = current_time
def input_map_size(): """ Prompts player to input map size. Returns: map_size (int) """ logger.info(text.dungeon_size_promt) logger.debug("expecting map size input from user") user_input = input().lower() map_size = None while not map_size: if (user_input.isdigit() and int(user_input) >= MIN_MAP_SIZE and int(user_input) <= MAX_MAP_SIZE): map_size = int(user_input) else: for key in map_sizes.keys(): if user_input.lower() == key: map_size = map_sizes[key] if not map_size: logger.debug("incorrect map size input from user") logger.info(text.dungeon_size_hint) logger.debug("expecting map size input from user") user_input = input() return map_size
def initialize(self, height, width, treasure_number, traps, start_pos): """ Initializes DungeonMap param: height (int) height of the map param: width (int) width of the map param: treasure_number (int) number of treasures on map param: traps (iterateble) traps to put on map param: start_pos (Position) player starting position on map """ try: is_input_valid = width * height > treasure_number + len(traps) except TypeError as error: raise DungeonMapInitializationError( "Incorrect parameter type in " "DungeonMap initialize. \n {}".fromat(str(error))) else: if not is_input_valid: try: raise DungeonMapInitializationError( "Incorrect parameters in " "DungeonMap initialize. Map can't fit all of the cells." ) #made because try daoesn't work without exept except DungeonMapInitializationError: raise self.width = width self.height = height self.cells = [[empty_cell.legend for i in range(height)] for j in range(width)] logger.debug("empty map generated") try: self.cells[start_pos.x][start_pos.y] = entrance_cell.legend except IndexError: raise DungeonMapInitializationError( "Incorrect parameters in " "DungeonMap initialize. Strating position is out of DungeonMap " "boundaries") while treasure_number > 0: pos = Position.generate_random_position(width, height) if self.cell(pos) == empty_cell.legend: self.cells[pos.x][pos.y] = treasure_cell.legend treasure_number -= 1 logger.debug("treasures generated") while traps: pos = Position.generate_random_position(width, height) if self.cell(pos) == empty_cell.legend: self.cells[pos.x][pos.y] = traps.pop() logger.debug("traps generated")
def input_number_from_boundaries(min_value, max_value): """ Prompts user to enter integer in given boundaries. return: int from given boundaries that is entered by user """ while True: try: number = int(input()) except ValueError: logger.debug("non-numeric input from user") logger.info("please enter number between {} {}". format(min_value, max_value)) else: if number >= min_value and number <= max_value: break else: logger.debug("input from user out of specified bounds") logger.info("please enter number between {} {}". format(min_value, max_value)) return number
def input_number_from_boundaries(min_value, max_value): """ Prompts user to enter integer in given boundaries. return: int from given boundaries that is entered by user """ user_input = input().lower() number = None while not number and number != 0: if (user_input.isdigit() and int(user_input) >= min_value and int(user_input) <= max_value): number = int(user_input) if not number: logger.debug("incorrect input from user") logger.info("please enter number between {} {}".format( min_value, max_value)) user_input = input() return number