Exemplo n.º 1
0
 def clear_floor(self, x, y, w, h):
     for room_x in range(x - 1, x + w + 1):
         for room_y in range(y - 1, y + h + 1):
             try:
                 create_floor(self.game_map, room_x, room_y)
             except:
                 pass
Exemplo n.º 2
0
    def create_tunnel(self, point1, point2, current_cave, map_width,
                      map_height):
        # run a heavily weighted random Walk
        # from point1 to point1
        print('create_tunnel random walk')
        drunkard_x = point2[0]
        drunkard_y = point2[1]
        while (drunkard_x, drunkard_y) not in current_cave:
            # ==== Choose Direction ====
            north = 1.0
            south = 1.0
            east = 1.0
            west = 1.0

            weight = 1

            # weight the random walk against edges
            if drunkard_x < point1[0]:  # drunkard is left of point1
                east += weight
            elif drunkard_x > point1[0]:  # drunkard is right of point1
                west += weight
            if drunkard_y < point1[1]:  # drunkard is above point1
                south += weight
            elif drunkard_y > point1[1]:  # drunkard is below point1
                north += weight

            # normalize probabilities so they form a range from 0 to 1
            total = north + south + east + west
            north /= total
            south /= total
            east /= total
            west /= total

            # choose the direction
            choice = random()
            if 0 <= choice < north:
                dx = 0
                dy = -1
            elif north <= choice < (north + south):
                dx = 0
                dy = 1
            elif (north + south) <= choice < (north + south + east):
                dx = 1
                dy = 0
            else:
                dx = -1
                dy = 0

            # ==== Walk ====
            # check collision at edges
            if (0 < drunkard_x + dx < map_width - 1) and (0 < drunkard_y + dy <
                                                          map_height - 1):
                drunkard_x += dx
                drunkard_y += dy
                if self.game_map.is_blocked(drunkard_x, drunkard_y):
                    create_floor(self.game_map, drunkard_x, drunkard_y)
Exemplo n.º 3
0
    def generate_level(self, game_map, dungeon_level, max_rooms, room_min_size,
                       room_max_size, map_width, map_height, player, entities,
                       particles, particle_systems, item_table, mob_table):
        # Creates an empty 2D array or clears existing array
        self.walk_iterations = max(self.walk_iterations,
                                   (map_width * map_height * 10))
        self.game_map = game_map
        self.dungeon_level = dungeon_level

        self.radius = max(map_width // 10, map_height // 10)

        self.random_walk_x = randint(self.radius, map_width - self.radius - 1)
        self.random_walk_y = randint(self.radius, map_height - self.radius - 1)

        # Modify Percent Goal Depending on Dungeon Level
        self._percentGoal = 0.1 + (self.dungeon_level * 0.015)

        self.filledGoal = map_width * map_height * self._percentGoal

        # Place Player at 1st Location
        # TODO: Sometimes player spawns inside a wall?
        x, y = self.random_walk_x, self.random_walk_y
        player.position.x, player.position.y = x, y

        self.game_map.tile_cost[y][x] = 99
        create_floor(game_map, x, y)
        self.encounters.append((x, y))

        for i in range(self.walk_iterations):
            self.walk(map_width, map_height)

            # Check for Encounter
            if self._filled % self.encounter_interval == 0:
                if self.encounter_within_proximity(self.random_walk_x,
                                                   self.random_walk_y):

                    if self.radius < self.random_walk_x < map_width - self.radius and self.radius < self.random_walk_y < map_height - self.radius:
                        room = Circle(game_map, self.random_walk_x,
                                      self.random_walk_y, self.radius,
                                      len(game_map.rooms) + 1)
                        game_map.rooms.append(room)
                        place_entities(self.game_map, self.dungeon_level, room,
                                       entities, item_table, mob_table)
                        self.encounters.append(
                            (self.random_walk_x, self.random_walk_y))
                else:
                    # TODO: Find a way to not allow multiple iteration checks for encounter_within_proximity
                    # Note: The below line is a lie. We're not really filling up more spaces.
                    self._filled += 1

            if self._filled >= self.filledGoal:
                break

        # Place Stairs at Last Location
        place_stairs(game_map, self.dungeon_level, self.random_walk_x,
                     self.random_walk_y)
Exemplo n.º 4
0
 def clean_up_map(self, map_width, map_height):
     if self.smooth_edges:
         for i in range(0, 5):
             # Look at each cell individually and check for smoothness
             for x in range(2, map_width - 2):
                 for y in range(2, map_height - 2):
                     if self.game_map.is_blocked(
                             x, y) and self.get_adjacent_walls_simple(
                                 x, y) <= self.smoothing:
                         create_floor(self.game_map, x, y)
Exemplo n.º 5
0
    def get_caves(self, map_width, map_height):
        # locate all the caves within self.game_map.tiles and store them in self.caves
        # print('locate all the caves within self.game_map.tiles and store them in self.caves')
        for x in range(1, map_width - 1):
            for y in range(1, map_height - 1):
                if not self.game_map.is_blocked(x, y):
                    self.flood_fill(x, y)

        for tile_set in self.caves:
            for x, y in tile_set:
                create_floor(self.game_map, x, y)

        # check for 2 that weren't changed.
        """
Exemplo n.º 6
0
    def generate_castle_entrance(self):
        x = self.end_area.x
        y = self.end_area.y
        w = self.end_area.width
        h = self.end_area.height
        self.create_walled_room(x - w // 2, y, w, h, False)
        for _y in range(y + 1, y + w - 1):
            place_tile(self.game_map, _y + (x - w // 2), 0, "47")

        for i in range(1 + x - w // 2, x + w // 2):
            place_tile(self.game_map, i, y + h - 1, "35")
        create_floor(self.game_map, x, y + h - 1)

        for i in range(1 + x - w // 2, x + w // 2):
            create_floor(self.game_map, i, y + h)
Exemplo n.º 7
0
    def generate_door(self, x, y, w, h, entities, particles):
        # Door
        poss_locations = []

        # Top
        poss_locations.extend((i, y) for i in range(x + 1, x + w - 1))
        # # Bottom
        poss_locations.extend((i, y + h - 1) for i in range(x + 1, x + w - 1))
        # # Left
        poss_locations.extend((x, j) for j in range(y + 1, y + h - 1))
        # # Right
        poss_locations.extend((x + w - 1, j) for j in range(y + 1, y + h - 1))

        # print('poss_locations:', poss_locations)
        # Two Doors
        shuffle(poss_locations)
        if randint(0, 4) == 1:
            door_x, door_y = poss_locations.pop()
            # print('door:', door_x, door_y)
            create_floor(self.game_map, door_x, door_y)
            door_index = "5"
            door_stats = TILESET.get(door_index)
            generate_object(door_x,
                            door_y,
                            entities,
                            self.game_map.map_objects,
                            particles,
                            self.game_map,
                            door_stats,
                            door_index,
                            item_list=None)

        door_x, door_y = poss_locations.pop()
        # print('door:', door_x, door_y)
        create_floor(self.game_map, door_x, door_y)
        door_index = "5"
        door_stats = TILESET.get(door_index)
        generate_object(door_x,
                        door_y,
                        entities,
                        self.game_map.map_objects,
                        particles,
                        self.game_map,
                        door_stats,
                        door_index,
                        item_list=None)

        return door_x, door_y
Exemplo n.º 8
0
    def assign_tiles(self, mold=False):
        # Assign Tiles from Grid
        for x in range(self.width):
            for y in range(self.height):
                if self.grid[x][y] == 1:
                    if randint(0, 6) == 1 and mold:
                        place_tile(self.game_map, x, y, '46')  # normal tree
                    else:
                        place_tile(self.game_map, x, y, '13')  # moldfy tree

                elif self.grid[x][y] == 0:
                    if randint(0, 4) == 1:
                        place_tile(self.game_map, x, y, '44')  # normal grass
                    elif randint(0, 6) == 1 and mold:
                        place_tile(self.game_map, x, y, '45')  # fungus grass
                    else:
                        create_floor(self.game_map, x, y)
Exemplo n.º 9
0
    def create_caves(self, map_width, map_height):
        # ==== Create distinct caves ====
        for i in range(0, self.iterations):
            # Pick a random point with a buffer around the edges of the map
            tile_x = randint(2, map_width - 3)  # (2,map_width-3)
            tile_y = randint(2, map_height - 3)  # (2,map_height-3)

            # if the cell's neighboring walls > self.neighbors, set it to 1
            if self.get_adjacent_walls(tile_x, tile_y) > self.neighbors:
                # self.game_map.tiles[tile_x][tile_y] = 1
                create_wall(self.game_map, tile_x, tile_y)
            # or set it to 0
            elif self.get_adjacent_walls(tile_x, tile_y) < self.neighbors:
                create_floor(self.game_map, tile_x, tile_y)

        # ==== Clean Up Map ====
        self.clean_up_map(map_width, map_height)
Exemplo n.º 10
0
    def generate_level(self, game_map, dungeon_level, max_rooms, room_min_size,
                       room_max_size, map_width, map_height, player, entities,
                       item_table, mob_table):
        # def generate_level(self, game_map, map_width, map_height):
        # Creates an empty 2D array or clears existing array
        self.game_map = game_map
        self.dungeon_level = dungeon_level
        self.map_width = map_width
        self.map_height = map_height

        print('Random Fill Map')
        self.random_fill_map(map_width, map_height)
        print('Create Caves')
        self.create_caves(map_width, map_height)
        print('Get Caves')
        self.get_caves(map_width, map_height)
        print('Connect Caves')
        self.connect_caves(map_width, map_height)
        print('Clean Up Map')
        self.clean_up_map(map_width, map_height)
        # Find Center of Caves
        print('find_cave_centers')
        self.find_cave_centers()

        # Check if Caves were Actually Generation, Recall Same Generation
        if not self.cave_centers:
            print('Couldn\'t generate caves. Restarting...')
            self.reset_generation()
            entities = [player]
            self.generate_level(game_map, dungeon_level, max_rooms,
                                room_min_size, room_max_size, map_width,
                                map_height, player, entities, item_table,
                                mob_table)
            return False

        # Place Player and Stairs, Open Floor
        # TODO: Connect caves 1 and 2
        player.position.x, player.position.y = self.cave_centers[0].center
        create_floor(game_map, player.position.x, player.position.y)
        x, y = self.cave_centers[-1].center
        entities.append(place_stairs(self.dungeon_level, x, y))
        create_floor(game_map, x, y)

        # TODO: Ensure there is a path for player and path to stairs

        # Spawn Entities
        for cave in self.cave_centers:
            place_entities(game_map, dungeon_level, cave, entities, item_table,
                           mob_table)
            # debug find centers

            # cx, cy = cave.center
            # print('cave center at: (%s, %s)' % (cx, cy))
            create_floor(game_map, cave.x, cave.y)
            # create_floor(game_map, cave.x, cave.y)
            # print('cave center at: (%s, %s)' % (cave.x, cave.y))

        self.print_generation_stats(entities)
Exemplo n.º 11
0
    def create_walled_room(self,
                           room_x,
                           room_y,
                           room_width,
                           room_height,
                           ruined=True):
        # Sets Tiles in to Become Passable, but add walls around
        for x in range(room_x, room_x + room_width):
            for y in range(room_y, room_y + room_height):
                if x == room_x or \
                        x == room_x + room_width - 1 or \
                        y == room_y or \
                        y == room_y + room_height - 1:

                    if ruined:
                        if randint(0, 100) < 80:
                            create_wall(self.game_map, x, y)
                    else:
                        create_wall(self.game_map, x, y)
                else:
                    if ruined and randint(0, 100) < 25:
                        create_floor(self.game_map, x, y)
                    else:
                        place_tile(self.game_map, x, y, "47")
Exemplo n.º 12
0
def create_v_tunnel(game_map, y1, y2, x):
    for y in range(min(y1, y2), max(y1, y2) + 1):
        create_floor(game_map, x, y)
Exemplo n.º 13
0
def create_h_tunnel(game_map, x1, x2, y):
    for x in range(min(x1, x2), max(x1, x2) + 1):
        create_floor(game_map, x, y)
Exemplo n.º 14
0
 def random_fill_map(self, map_width, map_height):
     for y in range(2, map_height - 2):
         for x in range(2, map_width - 2):
             # print("(",x,y,") = ",self.game_map.tiles[x][y])
             if random() >= self.wall_probability:
                 create_floor(self.game_map, x, y)
Exemplo n.º 15
0
    def walk(self, map_width, map_height):
        # ==== Choose Direction ====
        north = 1.0
        south = 1.0
        east = 1.0
        west = 1.0

        # weight the random walk against edges
        if self.random_walk_x < map_width * 0.25:  # random walk is at far left side of map
            east += self.weighted_toward_center
        elif self.random_walk_x > map_width * 0.75:  # random walk is at far right side of map
            west += self.weighted_toward_center
        if self.random_walk_y < map_height * 0.25:  # random walk is at the top of the map
            south += self.weighted_toward_center
        elif self.random_walk_y > map_height * 0.75:  # random walk is at the bottom of the map
            north += self.weighted_toward_center

        # weight the random walk in favor of the previous direction
        if self._previousDirection == "north":
            north += self.weighted_toward_previous_generation
        if self._previousDirection == "south":
            south += self.weighted_toward_previous_generation
        if self._previousDirection == "east":
            east += self.weighted_toward_previous_generation
        if self._previousDirection == "west":
            west += self.weighted_toward_previous_generation

        # normalize probabilities so they form a range from 0 to 1
        total = north + south + east + west

        north /= total
        south /= total
        east /= total
        west /= total

        # choose the direction
        choice = random()
        if 0 <= choice < north:
            dx = 0
            dy = -1
            direction = "north"
        elif north <= choice < north + south:
            dx = 0
            dy = 1
            direction = "south"
        elif north + south <= choice < north + south + east:
            dx = 1
            dy = 0
            direction = "east"
        else:
            dx = -1
            dy = 0
            direction = "west"

        # ==== Walk ====
        # check collision at edges
        if 0 < self.random_walk_x + dx < map_width - 1 and 0 < self.random_walk_y + dy < map_height - 1:
            self.random_walk_x += dx
            self.random_walk_y += dy
            # if self.game_map.tiles[self.random_walk_x][self.random_walk_y].blocked:
            if not self.game_map.walkable[self.random_walk_y][
                    self.random_walk_x]:
                create_floor(self.game_map, self.random_walk_x,
                             self.random_walk_y)
                self._filled += 1
            self._previousDirection = direction