Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def generate(self):
self.map_canvas.clear(CaveWall)
# First create a bunch of hallways and rooms.
# For now, just carve a big area, run a hallway through the middle, and
# divide either side into rooms.
area = Room.randomize(self.region, minimum_size=self.region.size // 2)
area.draw_to_canvas(self.map_canvas)
center = area.rect.center()
y0 = center.y - 2
y1 = center.y + 2
hallway = Rectangle(origin=Point(area.rect.left, center.y - 2), size=Size(area.rect.width, 5))
Room(hallway).draw_to_canvas(self.map_canvas)
top_space = area.rect.replace(bottom=hallway.top)
bottom_space = area.rect.replace(top=hallway.bottom)
rooms = []
for orig_space in (top_space, bottom_space):
space = orig_space
# This includes walls!
minimum_width = 7
# Note that the rooms overlap where they touch, so we subtract one
# from both the total width and the minimum width, in effect
# ignoring all the walls on one side
maximum_rooms = (space.width - 1) // (minimum_width - 1)
# The maximum number of rooms that will fit also affects how much
# wiggle room we're willing to have. For example, if at most 3 rooms
# rotated freely
side = random.choice([Direction.left, Direction.right])
# TODO assert region is big enough
room_size = Size(
random_normal_range(9, int(self.region.width * 0.4)),
random_normal_range(9, int(self.region.height * 0.4)),
)
room_position = self.region.center() - room_size // 2
room_position += Point(
random_normal_int(0, self.region.width * 0.1),
random_normal_int(0, self.region.height * 0.1),
)
room_rect = Rectangle(room_position, room_size)
self.room_region = room_rect
room = Room(room_rect)
cave_area = (
Blob.from_rectangle(self.region)
- Blob.from_rectangle(room_rect)
)
self.cave_region = cave_area
walls = [point for (point, _) in self.region.iter_border()]
floors = []
for point, edge in room_rect.iter_border():
if edge is side or edge.adjacent_to(side):
floors.append(point)
floors.append(point + side)
generate_caves(
self.viewport = self.world.current_map.rect
horizontal = self._adjust_viewport(
self.viewport.horizontal_span,
size.width,
player_position.x,
map.rect.horizontal_span,
)
vertical = self._adjust_viewport(
self.viewport.vertical_span,
size.height,
player_position.y,
map.rect.vertical_span,
)
self.viewport = Rectangle.from_spans(
horizontal=horizontal, vertical=vertical)
# viewport is from the pov of the map; negate it to get how much space
# is added or removed around the map
pad_left = - self.viewport.left
pad_top = - self.viewport.top
pad_right = (size.width - pad_left) - map_rect.width
pad_bottom = (size.height - pad_top) - map_rect.height
# TODO it's unclear when you're near the edge of the map, which i hate.
# should either show a clear border past the map edge, or show some
# kinda fade or whatever along a cut-off edge
map_canvas = urwid.CompositeCanvas(CellCanvas(map))
map_canvas.pad_trim_left_right(pad_left, pad_right)
map_canvas.pad_trim_top_bottom(pad_top, pad_bottom)
return map_canvas
def randomize(cls, region, *, minimum_size=Size(5, 5)):
"""Place a room randomly in a region, randomizing its size and position.
"""
# TODO need to guarantee the region is big enough
size = Size(
random_normal_range(minimum_size.width, region.width),
random_normal_range(minimum_size.height, region.height),
)
left = region.left + random.randint(0, region.width - size.width)
top = region.top + random.randint(0, region.height - size.height)
rect = Rectangle(Point(left, top), size)
return cls(rect)
def __contains__(self, other):
if isinstance(other, Rectangle):
return (
self.top <= other.top and
self.bottom >= other.bottom and
self.left <= other.left and
self.right >= other.right
)
elif isinstance(other, Point):
return (
self.left <= other.x <= self.right and
self.top <= other.y <= self.bottom
)
else:
return False
def to_rect(self, point):
return Rectangle(point, self)