Пример #1
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
Пример #2
0
    def draw_character(self):

        health_info = "".join(
            ['Health: ', *["[#]" for x in range(0, self.health)], 
            *["[ ]" for x in range(self.health, 3)]])

        treasures_info = "".join(
            ['Treasures: ', *["[@]" for x in range(0, self.treasures)], 
            *["[ ]" for x in range(self.treasures, 3)]])
        
        my_logger.info(" ".join([health_info, treasures_info]))
Пример #3
0
    def make_move(self, move_direction, width, height):
        """
        Used to change coordinates of character
        """
        try:

            if not move_direction in set(['w', 'd', 's', 'a']):

                raise MoveError("Appeared while player has moved")

        except MoveError as move_error:

            my_logger.exception(move_error)
            return False

        old_x = self.player_x
        old_y = self.player_y

        if move_direction == 'w':

            if self.player_y > 0:

                self.player_y -=1
                my_logger.info('You have moved up')

        elif move_direction == 'd':

            if self.player_x < width - 1:

                self.player_x +=1
                my_logger.info('You have moved right')

        elif move_direction == 's':

            if self.player_y < height - 1:

                self.player_y +=1
                my_logger.info('You have moved down')

        elif move_direction == 'a':

            if self.player_x > 0:

                self.player_x -=1
                my_logger.info('You have moved left')

        if old_x == self.player_x and old_y == self.player_y:

            my_logger.info("There is a wall!")

        return True
    def load_game(self):
        """
        Game load (pickle!)
        """
        my_logger.info("Loading game...")
        in_file = open('dungeon.sav', 'rb')

        data = pickle.load(in_file)

        [
            self.dungeon_map.dungeon_map, self.dungeon_map.map_size,
            self.player_map.dungeon_map, self.player.player_x,
            self.player.player_y, self.player.health, self.player.treasures
        ] = data
        my_logger.info("Game has been loaded!")
    def run_farame(self):
        """
        Game frame. Returns true if game could be resumed and false otherwise
        """
        ret_value = True
        move = input(
            '\nEnter your move, please (w - up, d - right, s - down, a - left), or "save" for save game:\n'
        )

        if move == "save":

            self.save_game()
            ret_value = False

        self.player.make_move(move, *self.dungeon_map.map_size)

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

        if self.dungeon_map.get_cell_content(self.player.player_x,
                                             self.player.player_y) == 'T':

            self.dungeon_map.set_cell_content(self.player.player_x,
                                              self.player.player_y, '-')
            self.player.add_treasure()

        elif self.dungeon_map.get_cell_content(self.player.player_x,
                                               self.player.player_y) == 'X':

            self.dungeon_map.set_cell_content(self.player.player_x,
                                              self.player.player_y, '-')
            self.player.apply_damage()

        self.player.draw_character()

        if self.player.is_dead():

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

        elif self.player.is_winner():

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

        return ret_value
Пример #6
0
    def enemy_update(self):

        while self.is_game_ongoing:

            if time.clock() - self.time > 3.0:

                self.time = time.clock()

                self.player_map.set_cell_content(self.enemy.enemy_x,
                                                 self.enemy.enemy_y,
                                                 self.enemy_cell)

                move_direction = random.choice(['w', 'a', 's', 'd'])
                self.enemy.make_move(move_direction,
                                     self.dungeon_map.map_size[0],
                                     self.dungeon_map.map_size[1])

                self.enemy_cell = self.player_map.get_cell_content(
                    self.enemy.enemy_x, self.enemy.enemy_y)

                if self.enemy_cell != '?':

                    self.player_map.set_cell_content(self.enemy.enemy_x,
                                                     self.enemy.enemy_y, '%')

                self.player_map.draw_map()
                self.player.draw_character()

                if self.player.player_x == self.enemy.enemy_x and self.player.player_y == self.enemy.enemy_y:

                    self.player.apply_damage()
                    self.enemy.randomize_initial_position(self.dungeon_map)
                    my_logger.info('\n %[ You have been beaten by enemy!')

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

                if self.player.is_dead():

                    self.is_game_ongoing = False

            else:

                time.sleep(0.1)
Пример #7
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()
Пример #8
0
    def setup_new_game(self):
        """
        This function is used to generate new map of size, specified by user
        """
        while True:

            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]
                break

            else:

                try:

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

                except ValueError as val_error:

                    my_logger.exception(val_error)
                    my_logger.error("Try to enter map size once again!")

        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.enemy.randomize_initial_position(self.dungeon_map)
    def draw_map(self):

        for row in self.dungeon_map:

            my_logger.info("".join(row))
    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
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 make_move(move_direction, player_position, map_size):
    """
    Changes player position according to user input
    """

    if not move_direction in set(['w', 'd', 's', 'a']):

        my_logger.info('Wrong direction! Try again!')

    old_position = player_position[:]

    if move_direction == 'w':

        if player_position[1] > 0:

            player_position[1] -= 1
            my_logger.info('You have moved up')

    elif move_direction == 'd':

        if player_position[0] < map_size[0] - 1:

            player_position[0] += 1
            my_logger.info('You have moved right')

    elif move_direction == 's':

        if player_position[1] < map_size[1] - 1:

            player_position[1] += 1
            my_logger.info('You have moved down')

    elif move_direction == 'a':

        if player_position[0] > 0:

            player_position[0] -= 1
            my_logger.info('You have moved left')

    if old_position == player_position:

        my_logger.info("There is a wall!")
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")
    def make_move(self, move_direction, width, height):

        if not move_direction in set(['w', 'd', 's', 'a']):

            my_logger.info('Wrong direction! Try again!')
            return False

        old_x = self.player_x
        old_y = self.player_y

        if move_direction == 'w':

            if self.player_y > 0:

                self.player_y -= 1
                my_logger.info('You have moved up')

        elif move_direction == 'd':

            if self.player_x < width - 1:

                self.player_x += 1
                my_logger.info('You have moved right')

        elif move_direction == 's':

            if self.player_y < height - 1:

                self.player_y += 1
                my_logger.info('You have moved down')

        elif move_direction == 'a':

            if self.player_x > 0:

                self.player_x -= 1
                my_logger.info('You have moved left')

        if old_x == self.player_x and old_y == self.player_y:

            my_logger.info("There is a wall!")

        return True