def build_leg (rooms_tall=2, rooms_wide=2, make_corridor=True, do_cleanup=True): """ Create and return a "leg" to be used with add_leg. :``rooms_tall``: How many rooms tall to make the leg. *Default 2*. :``rooms_wide``: How many rooms wide to make the leg. *Max 2. Default 2*. :``make_corridor``: Include a corridor when building. *Default True*. :``do_cleanup``: Perform corridor, etc, clean-up when built. *Default True*. """ assert rooms_wide >= 1 and rooms_wide <= 2 assert rooms_tall >= 1 new_rooms = collection.ShapeCollection() for row in xrange(rooms_tall): rooms = [] for room in xrange(rooms_wide): rooms.append(Room().as_shape()) this_row = collection.ShapeCollection() this_row = shape.adjoin(rooms.pop(), this_row, overlap=-1, collect=True) for room in rooms: this_row = shape.adjoin(this_row, room, overlap=-1, collect=True) new_rooms = shape.underneath(this_row, new_rooms, overlap=1, collect=True) return new_rooms
def join_row_rooms (row, left_corr=False, right_corr=False, check_offset=False): """ Given a list of rooms, joins them together as a ShapeCollection. :``row``: A list of Room objects that should be placed in a row. *Required*. :``left_corr``: If true, leaves a gap between the first and second rooms to make space for a corridor. *Default False*. :``right_corr``: If true, leaves a gap between the last and second-last rooms to make space for a corridor. *Default False*. :``check_offset``: If true, compares the room heights to see if they need to be offset from the top. *Default False*. """ assert(len(row) > 2) first_room = row[0].as_shape() second_room = row[1].as_shape() # Does some weird stuff to offset everything offset_both = False if check_offset and first_room.height() == second_room.height(): offset_both = True # Join the first two rooms. top_offset = 0 if check_offset: top_offset = 2 overlap = 1 if left_corr: overlap = -1 row_collection = shape.adjoin(first_room, second_room, top_offset=top_offset, overlap=overlap, collect=True, offset_both=offset_both) # Join the middle rooms. for curr in row[2:-1]: room_shape = curr.as_shape() to = top_offset if check_offset and (room_shape.height() == first_room.height() and not offset_both or room_shape.height() > first_room.height()): to = 0 row_collection = shape.adjoin(row_collection, room_shape, top_offset=to, overlap=1, collect=True, offset_both=offset_both) # Join the last room. last_room = row[-1].as_shape() if check_offset and (last_room.height() == first_room.height() and not offset_both or last_room.height() > first_room.height()): top_offset = 0 overlap = 1 if right_corr: overlap = -1 row_collection = shape.adjoin(row_collection, last_room, top_offset=top_offset, overlap=overlap, collect=True) return row_collection
def build_leg (rooms_tall=2, rooms_wide=2, width_left=12, width_right=12, make_corridor=True, do_cleanup=True): """ Create and return a "leg" to be used with add_leg. :``rooms_tall``: How many rooms tall to make the leg. *Default 2*. :``rooms_wide``: How many rooms wide to make the leg. *Max 2. Default 2*. :``width_left``: The width of the leftmost rooms. *Default 12*. :``width_right``: The width of the rightmost rooms. *Default 12*. :``make_corridor``: Include a corridor when building. *Default True*. :``do_cleanup``: Perform corridor, etc, clean-up when built. *Default True*. """ assert rooms_wide >= 1 and rooms_wide <= 2 assert rooms_tall >= 1 leg_rooms = collection.ShapeCollection() if width_left == None: width_left = random.choice(ROOM_WIDTH_LIST) if width_right == None: width_right = random.choice(ROOM_WIDTH_LIST) heights = [] for r in xrange(rooms_tall): heights.append(7) for column in xrange(rooms_wide): this_col = collection.ShapeCollection() width = width_left if column > 0: width = width_right height_list = heights[:] if len(heights) > 1 and one_chance_in(5): indices = range(len(height_list)) small = random.choice(indices) indices.remove(small) large = random.choice(indices) height_list[small] -= 1 height_list[large] += 2 else: large = random.choice(xrange(len(height_list))) height_list[large] += 1 for row in xrange(rooms_tall): new_room = room.Room(width=width,height=height_list[row]).as_shape() # print "new_room height: %s, this_col height: %s" % (new_room.height(), this_col.height()) this_col = shape.underneath(new_room, this_col, offset_second=False, overlap=1, collect=True) # print "leg_rooms width: %s, this_col width: %s" % (leg_rooms.width(), this_col.width()) leg_rooms = shape.adjoin(leg_rooms, this_col, overlap=-1, collect=True) return leg_rooms
#!/usr/bin/env python """ unit test for manor building. """ from builder import room, builder from library import shape if __name__=="__main__": width1 = 8 width2 = 10 print "width1: %s, width2: %s" % (width1, width2) overlaps = [-1, 0, 1] for o in overlaps: print "\noverlap = %s:" % o room1 = room.Room(width=width1).as_shape() room2 = room.Room(width=width2).as_shape() combined = shape.adjoin(room1, room2, overlap=o, collect=True) m = builder.BuilderCollection(combined) print m.combine() for r in m.rooms: rm = m.get_room(r) print "Room %s: width=%s, start=(%s), end=(%s)" % (r, rm.width(), rm.pos(), rm.pos() + rm.size() - 1)
def base_builder (): """ Attempts to build a manor based on the style provided. It returns ShapeCollection and a list of Room objects. :``style``: One of ``ONE_CORRIDOR``, ``L_CORRIDOR`` or ``Z_CORRIDOR``. Currently on ``ONE_CORRIDOR`` is supported. *Default ONE_CORRIDOR*. """ # Top row of rooms row1 = [] # Corridor, then bottom row of rooms row2 = [] # We start with the entrance hall and add rooms on either side of it # until we have a minimum of six and a maximum of ten entrance_hall = Room() left = 0 right = 0 row2.append(entrance_hall) while len(row2) <= 5: # If we have six rooms, one in three chance of not adding any more # rooms. if len(row2) > 4 and random.randint(1, 4) == 1: break new_room = Room() if left > right: row2.append(new_room) right += 1 elif left < right: row2.insert(0, new_room) left += 1 else: side = random.randint(-1, 0) if side == -1: right += 1 else: left += 1 row2.insert(side, new_room) while len(row1) < len(row2): new_room = Room() row1.append(new_room) # Now, adjust the rooms at either end to compensate for the corridor: # 1. We can adjust two rooms on the bottom level for height, 2 on the # top for width. # 2. We can adjust one on the bottom and one on the top for height, and # the opposites for width. # 3. We can adjust two rooms on the top level for height, 2 on the # bottom for width. adjust_bottom = random.randint(0, 2) top_offset = 2 overlap = 3 if adjust_bottom == 2: overlap = 1 row2[0].height += 2 row2[-1].height += 2 row1[0].width += 2 row1[-1].width += 2 row2[1].width += 2 row2[-2].width += 2 elif adjust_bottom == 1: side_adjusted = random.randint(-1, 0) side_not_adjusted = -side_adjusted-1 row2[side_adjusted].height += 2 row1[side_not_adjusted].height += 2 row2[side_not_adjusted].width += 2 row1[side_adjusted].width += 2 elif adjust_bottom == 0: overlap = 3 row1[0].height += 2 row1[-1].height += 2 row2[0].width += 2 row2[-1].width += 2 row1[1].width += 2 row1[-2].width += 2 # Now, start drawing it! YAY! # First row first_room = row1[0].as_shape() second_room = row1[1].as_shape() row1_collection = shape.adjoin(first_room, second_room, overlap=1, collect=True) for room in row1[2:]: row1_collection = shape.adjoin(row1_collection, room.as_shape(), overlap=1, collect=True) # second row first_room = row2[0].as_shape() second_room = row2[1].as_shape() # Does some weird stuff to offset everything offset_both = False if first_room.height() == second_room.height(): offset_both = True row2_collection = shape.adjoin(first_room, second_room, top_offset=top_offset, overlap=1, collect=True, offset_both=offset_both) for room in row2[2:]: to = top_offset room_shape = room.as_shape() if room_shape.height() == first_room.height() and not offset_both or room_shape.height() > first_room.height(): to = 0 row2_collection = shape.adjoin(row2_collection, room_shape, top_offset=to, overlap=1, collect=True) # Finally, make a corridor! room_width = Room().width room_height = Room().height my_collection = shape.underneath(row1_collection, row2_collection, overlap=overlap, collect=True) manor = ManorCollection(my_collection) corridor_length = my_collection.width() - room_width * 2 corridor = MainCorridor(shape.Row(width=corridor_length, fill=".")) manor.append(collection.ShapeCoord(corridor, coord.Coord(room_width, room_height))) return manor