def set_map_size(self, width, height):

        if isinstance(width, int) and isinstance(height, int):

            if width < 2:

                width = 2

            elif width > 119:

                width = 119

            if height < 2:

                height = 2

            elif height > 30:

                height = 30

            self.map_size = [width, height]
            my_logger.debug("Map size has been stored successfully")
            return True

        else:

            my_logger.error("Wrong size type! Please, check the input")
            return False
    def generate_map(self):

        width = self.map_size[0]
        height = self.map_size[1]

        cells_count = width * height
        treasures_count = ceil((cells_count) / 20)
        trap_count = ceil((cells_count) / 10)

        my_logger.debug("Traps and treasures quantity has been calculated")

        my_logger.debug("Generating map...")

        self.dungeon_map = ['T' for x in range(0, treasures_count)]
        self.dungeon_map.extend(['X' for x in range(0, trap_count)])
        self.dungeon_map.extend([
            '-' for x in range(0, cells_count - treasures_count - trap_count)
        ])

        shuffle(self.dungeon_map)

        self.dungeon_map = [
            self.dungeon_map[x * width:x * width + width]
            for x in range(0, height)
        ]
Exemplo n.º 3
0
    def setup_game(self):
        """
        Game startup method: user should choose between playing new game or loading save
        """
        my_logger.debug("Game start choice")
        start_game_choice = input(
            'Enter "y" if you want to play a new game or\n"load" if you want to load existing game:\n'
        )
        my_logger.debug("Game start choice handling")

        if start_game_choice == "load":

            try:

                self.load_game()

            except (FileNotFoundError, pickle.UnpicklingError) as file_error:

                my_logger.exception(file_error)

                if isinstance(file_error, FileNotFoundError):

                    my_logger.error(
                        "There is no dungeon.sav file! Start a new game instead!"
                    )

                elif isinstance(file_error, pickle.UnpicklingError):

                    my_logger.error(
                        "dungeon.sav file is corrupted! Start a new game instead!"
                    )

                self.setup_new_game()

        else:

            self.setup_new_game()

        self.player_map.update_map(self.dungeon_map, self.player.player_x,
                                   self.player.player_y)
        self.player_map.draw_map()
        self.is_game_ongoing = True

        self.enemy_last_position = [self.enemy.enemy_x, self.enemy.enemy_y]
        self.enemy_thread = threading.Thread(target=self.enemy_update)
        self.enemy_thread.start()
Exemplo n.º 4
0
    def setup_game(self):
        """
        Game startup method: user should choose between playing new game or loading save
        """
        my_logger.debug("Game start choice")
        start_game_choice = input(
            'Enter "y" if you want to play a new game or\n"load" if you want to load existing game:\n'
        )
        my_logger.debug("Game start choice handling")

        if start_game_choice == "load":

            self.load_game()

        else:

            map_request = input(
                'Enter preferable map size in format "width:height", or just press enter to play with default map:\n'
            )
            my_logger.info("Generating map...")

            if not len(map_request):

                map_size = [20, 10]

            else:

                map_size = [int(token) for token in map_request.split(':')]

            self.dungeon_map.set_map_size(*map_size)
            self.dungeon_map.generate_map()
            my_logger.info("Map has been generated successfully!")

            self.player_map.set_map_size(*map_size)
            self.player_map.init_map()

            self.player.reset()
            self.player.randomize_initial_position(self.dungeon_map)

        self.player_map.update_map(self.dungeon_map, self.player.player_x,
                                   self.player.player_y)
        self.player_map.draw_map()
Exemplo n.º 5
0
    def randomize_initial_position(self, dungeon_map):

        my_logger.debug("Trying to find empty place for palyer...")

        while True:

            self.player_x = randint(0, dungeon_map.map_size[0] - 1)
            self.player_y = randint(0, dungeon_map.map_size[1] - 1)

            if dungeon_map.get_cell_content(self.player_y, self.player_x) != '-':

                continue

            else:

                break

        my_logger.debug("Empty place for palyer has been found")

        return None
    def set_map_size(self, width, height):

        if isinstance(width, int) and isinstance(height, int):

            try:

                if width < 5:

                    raise MapSizeError("", width, height)
                    width = 5

                elif width > 119:

                    raise MapSizeError("", width, height)
                    width = 119

                elif height < 5:

                    raise MapSizeError("", width, height)
                    height = 5

                elif height > 30:

                    raise MapSizeError("", width, height)
                    height = 30

            except MapSizeError as map_size_error:

                my_logger.exception(map_size_error)
                my_logger.error("Map size will be resetted to default value!")
                self.reset_map_size()
                return False

            self.map_size = [width, height]
            my_logger.debug("Map size has been stored successfully")
            return True

        else:

            my_logger.error("Wrong size type! Please, check the input")
            return False
    def randomize_initial_position(self, dungeon_map):
        """
        Enemy position randomize. Used at start and after biting player
        """
        my_logger.debug("Trying to find empty place for enemy...")

        while True:

            self.enemy_x = randint(0, dungeon_map.map_size[0] - 1)
            self.enemy_y = randint(0, dungeon_map.map_size[1] - 1)

            if dungeon_map.get_cell_content(self.enemy_y, self.enemy_x) != '-':

                continue

            else:

                break

        my_logger.debug("Empty place for enemy has been found")

        return None
def spawn_player(width, height, dungeon_map):
    """
    Parameters corresponds to map size
    """
    my_logger.debug("Trying to find empty place for palyer...")

    while True:

        player_x = randint(0, width - 1)
        player_y = randint(0, height - 1)

        if dungeon_map[player_y][player_x] != '-':

            continue

        else:

            break

    my_logger.debug("Empty place for palyer has been found")

    return [player_x, player_y]
    def update_map(self, real_map, player_x, player_y):

        my_logger.debug("Checking for wall near player...")

        min_row_index = player_y - 1 if player_y - 1 > 0 else 0
        max_row_index = player_y + 2 if player_y + 1 < self.map_size[
            1] else self.map_size[1]
        row_range = range(min_row_index, max_row_index)

        min_column_index = player_x - 1 if player_x - 1 > 0 else 0
        max_column_index = player_x + 2 if player_x + 1 < self.map_size[
            0] else self.map_size[0]
        column_range = range(min_column_index, max_column_index)

        my_logger.debug("Wall check done")

        my_logger.debug("Checking for treasures and traps around")

        is_treasure = False
        is_trap = False

        for y in row_range:

            for x in column_range:

                if real_map.get_cell_content(x, y) == 'T':

                    is_treasure = True

                elif real_map.get_cell_content(x, y) == 'X':

                    is_trap = True

        if is_treasure and is_trap:

            cell_filler = '!'

        elif is_treasure:

            cell_filler = 't'

        elif is_trap:

            cell_filler = 'x'

        else:

            cell_filler = '-'

        my_logger.debug("Treasures and traps check done")

        my_logger.debug("Making output for player")

        for y in row_range:

            for x in column_range:

                if self.dungeon_map[y][x] == '@':

                    self.dungeon_map[y][x] = '-'

                elif not self.dungeon_map[y][x] == '-':

                    self.dungeon_map[y][x] = cell_filler

        self.dungeon_map[player_y][player_x] = '@'

        if is_treasure:

            my_logger.info('There is a treasure!')

        elif is_trap:

            my_logger.info('There is a trap!')

        my_logger.debug("Player output finished")

        return None
from dungeon_game import Game
from dungeon_logger import my_logger

game_instance = Game()

while True:

    game_instance.setup_game()

    while game_instance.run_farame():

        pass

    decision = input('Do you want to play again? y/n:\n')

    if decision == 'y':

        my_logger.debug("Restarting game")
        continue

    else:

        my_logger.debug("Abandoning game")
        break
Exemplo n.º 11
0
def dungeon_map_generator(width=20, height=10):
    """
    Generates random map with at least 10% cells occupied with traps and 5% with treasures.
    Rounding quantity of special cells performed to higher value (ceil)
    """

    my_logger.debug("Checking correctness of input...")

    if not (isinstance(width, int) and isinstance(height, int)):

        my_logger.info(
            'Wrong cell size! Width and height should be positive integers\n')
        return None

    if width < 2:

        width = 2

    elif width > 119:

        width = 119

    if height < 2:

        height = 2

    elif height > 30:

        height = 30

    my_logger.debug("Input check done")

    my_logger.debug("Calculating amount of traps and treasures...")

    cells_count = width * height
    treasures_count = ceil((cells_count) / 20)
    trap_count = ceil((cells_count) / 10)

    my_logger.debug("Traps and treasures quantity has been calculated")

    my_logger.debug("Generating map...")

    dungeon_map = ['T' for x in range(0, treasures_count)]
    dungeon_map.extend(['X' for x in range(0, trap_count)])
    dungeon_map.extend(
        ['-' for x in range(0, cells_count - treasures_count - trap_count)])

    shuffle(dungeon_map)

    dungeon_map = [
        dungeon_map[x * width:x * width + width] for x in range(0, height)
    ]

    my_logger.debug("Map has been generated")

    return dungeon_map
    def make_move(self, move_direction, width, height):
        """
        Used to change coordinates of enemy
        A little bit redundant method, however clear enough.
        Enemy moves in any case, through repelling from walls if the way has been blocked by the wall
        """
        if move_direction == 'w':

            if self.enemy_y > 0:

                self.enemy_y -=1
                my_logger.debug('Enemy have moved up')

            else:

                self.enemy_y +=1
                my_logger.debug('Enemy have moved down')

        elif move_direction == 'd':

            if self.enemy_x < width - 1:

                self.enemy_x +=1
                my_logger.debug('Enemy have moved right')

            else:

                self.enemy_x -=1
                my_logger.debug('Enemy have moved left')

        elif move_direction == 's':

            if self.enemy_y < height - 1:

                self.enemy_y +=1
                my_logger.debug('Enemy have moved down')

            else:

                self.enemy_y -=1
                my_logger.debug('Enemy have moved up')

        elif move_direction == 'a':

            if self.enemy_x > 0:

                self.enemy_x -=1
                my_logger.debug('Enemy have moved left')

            else:

                self.enemy_x +=1
                my_logger.debug('Enemy have moved right')

        return None
Exemplo n.º 13
0
from game_functions import game_loop
from dungeon_logger import my_logger
from dungeon_logger import log_decorator

while True:

    my_logger.debug("Entering main game function")

    game_loop()

    my_logger.debug("Main game function has finished")

    decision = input('Do you want to play again? y/n:\n')

    if decision == 'y':

        my_logger.debug("Restarting game")
        continue

    else:

        my_logger.debug("Abandoning game")
        break


def check_around(player_x, player_y, map_size, dungeon_map, player_map):
    """
    This function performs check for treasures/traps in surrounding cells
    """

    is_treasure = False
    is_trap = False

    my_logger.debug("Checking for wall near player...")

    min_row_index = player_y - 1 if player_y - 1 > 0 else 0
    max_row_index = player_y + 2 if player_y + 1 < map_size[1] else map_size[1]
    row_range = range(min_row_index, max_row_index)

    min_column_index = player_x - 1 if player_x - 1 > 0 else 0
    max_column_index = player_x + 2 if player_x + 1 < map_size[
        0] else map_size[0]
    column_range = range(min_column_index, max_column_index)

    my_logger.debug("Wall check done")

    my_logger.debug("Checking for treasures and traps around")

    for y in row_range:

        for x in column_range:

            if dungeon_map[y][x] == 'T':

                is_treasure = True

            elif dungeon_map[y][x] == 'X':

                is_trap = True

    if is_treasure and is_trap:

        fill_cells = '!'

    elif is_treasure:

        fill_cells = 't'

    elif is_trap:

        fill_cells = 'x'

    else:

        fill_cells = '-'

    my_logger.debug("Treasures and traps check done")

    my_logger.debug("Making output for player")

    for y in row_range:

        for x in column_range:

            if not player_map[y][x] == '-':

                player_map[y][x] = fill_cells

    player_map[player_y][player_x] = '@'

    for row in player_map:

        my_logger.info("".join(row))

    if is_treasure:

        my_logger.info('There is a treasure!')

    elif is_trap:

        my_logger.info('There is a trap!')

    my_logger.debug("Player output finished")

    return (is_treasure, is_trap)
def game_loop():
    """
    Main game function contains game loop and some surrounding stuff
    """
    my_logger.debug("Game start choice")
    start_game_choice = input(
        'Enter "y" if you want to play a new game or\n"load" if you want to load existing game:\n'
    )
    my_logger.debug("Game start choice handling")

    if start_game_choice == "load":

        my_logger.info("Loading game...")
        in_file = open('dungeon.sav', 'rb')

        data = pickle.load(in_file)

        game_map = data[0]
        player_map = data[1]
        player_position = data[2]
        map_size = data[3]
        my_logger.info("Game has been loaded!")

    else:

        map_request = input(
            'Enter preferable map size in format "width:height", or just press enter to play with default map:\n'
        )
        my_logger.info("Generating map...")

        if not len(map_request):

            map_size = [20, 10]

        else:

            map_size = [int(token) for token in map_request.split(':')]

        game_map = dungeon_map_generator(*map_size)

        player_map = [['?' for x in range(0, map_size[0])]
                      for y in range(0, map_size[1])]

        player_position = spawn_player(*map_size, game_map)

        my_logger.info("Map has been generated successfully!")

    my_logger.debug("Checking around...")
    check_around(*player_position, map_size, game_map, player_map)
    my_logger.debug("Check around has been done")

    my_logger.debug("Entering main game loop...")

    while True:

        move = input(
            '\nEnter your move, please (w - up, d - right, s - down, a - left), or "save" for save game:\n'
        )

        if move == "save":

            data = [game_map, player_map, player_position, map_size]

            out_file = open('dungeon.sav', 'wb')

            pickle.dump(data, out_file)
            break

        player_map[player_position[1]][player_position[0]] = '-'

        make_move(move, player_position, map_size)

        check_around(*player_position, map_size, game_map, player_map)

        if game_map[player_position[1]][player_position[0]] == 'T':

            my_logger.info("\n>>>This is a treasure! You are victorious!<<<\n")
            break

        elif game_map[player_position[1]][player_position[0]] == 'X':

            my_logger.info("\n}}}This is a trap! You loose!{{{\n")
            break

        else:

            continue

    my_logger.debug("Main game loop has stopped")

    my_logger.debug("Printing game map...")

    for row in game_map:

        my_logger.info("".join(row))

    my_logger.debug("Game map has been printed")