def _interior_garden(w, h, wall_material, floor_material): M = Map(w, h, fill_cell=C.floor_flagged) garden_part = Map(w // 2, h, fill_cell=C.flora_grass) for y in range(0, h): garden_part[w // 2 - 1, y] = C.floor_flagged() for x in range(1, w // 2 - 1): for y in range(1, 4): garden_part[x, y] = C.floor_flagged() for x in range(2, w // 2): garden_part[x, 2].put(T.water_trough()) for y in range(h - 3, h): garden_part[0, y] = C.flora_tree() garden_part[1, y].put(T.water_trough()) garden_part[2, y] = C.flora_flower() garden_part[w // 2 - 2, 0] = C.flora_flower() garden_part[0, h - 5].put(T.furniture_sofa()) garden_part[1, h - 5].put(T.furniture_table_round()) garden_part[2, h - 6].put(T.urn()) M.meld(garden_part, 0, 0) garden_part2 = deepcopy(garden_part) garden_part2.hmirror() M.meld(garden_part2, w // 2 + w % 2, 0) for x in range(0, w // 2 - 1): M[x, h - 4] = C.floor_flagged() M.scatter(0, 0, w - 1, h - 1, [A.animal_cat()]) return M
def dungeon_drunkard(w, h, length=None, turn_chance=0.4): M = Map(w, h, fill_cell=C.wall_dungeon_smooth) if not length: length = int(w * h / 2) worm_x = random.randint(int(w * 0.3), int(w * 0.6)) worm_y = random.randint(int(h * 0.3), int(h * 0.6)) move = random.choice([NORTH, SOUTH, EAST, WEST]) for _ in range(length): M[worm_x, worm_y] = C.floor_flagged() worm_x, worm_y, move = _move_worm(M, worm_x, worm_y, move, turn_chance) return M
def _crush_walls(M, room_size, delete_chance): """Randomly remove walls with delete_chance.""" w, h = M.get_size() x_rooms = ((w - 1) // (room_size + 1)) y_rooms = ((h - 1) // (room_size + 1)) for i in range(1, y_rooms): for j in range(1, x_rooms): y = i * (room_size + 1) x = j * (room_size + 1) + 1 chance = random.random() if chance < delete_chance: for _ in range(room_size): M[x, y] = C.floor_flagged() x += 1 for i in range(1, y_rooms): for j in range(1, x_rooms): y = i * (room_size + 1) + 1 x = j * (room_size + 1) chance = random.random() if chance < delete_chance: for _ in range(room_size): M[x, y] = C.floor_flagged() y += 1
def building_housebarn(w=30, h=15, material=None): """ Construct the housebarn (also known as longhouse) building interior. Parameters ---------- w : int Map width h : int Map height material : string Wall material. Can be "wooden", "stone" or None. If None, a random material will be chosen. """ # Initial checks. Don't accept: # - Too small buildings # - Too long/square buildings # - Wall types that are not "stone" or "wooden" if w < 10 or h < 10: raise ValueError('Building is too small: w/h < 10') if not material: material = random.choice(['wooden', 'stone']) if material not in ('wooden', 'stone'): raise ValueError('Material should be "stone" or "wooden"') wall_cell_type = C.wall_stone if material == 'stone' else C.wall_plank is_horizontal = True if w >= h else False if is_horizontal: if w < h * 2 or w > h * 3: raise ValueError('Building is too long or too short.') else: if h < w * 2 or h > w * 3: raise ValueError('Building is too long or too short.') # If parameters are vertial, we firstly construct horizontal building then transpose it. # It allows not to use two additional different subtypes of the building which will simplify the code. if not is_horizontal: w, h = h, w M = Map(w, h, fill_cell=C.floor_flagged) # Create outward walls for x in range(w): M[x, 0] = wall_cell_type() M[x, h - 1] = wall_cell_type() for y in range(h): M[0, y] = wall_cell_type() M[w - 1, y] = wall_cell_type() # Randomly choose where the living part is living_left = random.choice([True, False]) living_wall_x = None barn_wall_x = None # Place central doors/corridor and calculate X-positions for vertical walls if w % 2 == 0: M[w // 2, 0] = C.floor_flagged() M[w // 2 - 1, 0] = C.floor_flagged() M[w // 2, h - 1] = C.floor_flagged() M[w // 2 - 1, h - 1] = C.floor_flagged() living_wall_x = (w // 2 - 3) if living_left else (w // 2 + 2) barn_wall_x = (w // 2 + 2) if living_left else (w // 2 - 3) else: M[w // 2, 0] = C.door_closed_wooden() M[w // 2, h - 1] = C.door_closed_wooden() living_wall_x = (w // 2 - 2) if living_left else (w // 2 + 2) barn_wall_x = (w // 2 + 2) if living_left else (w // 2 - 2) # Place vertical walls for i in range(1, h // 3): M[living_wall_x, i] = wall_cell_type() M[living_wall_x, h - i - 1] = wall_cell_type() for i in range(1, h - 1): M[barn_wall_x, i] = C.wall_fence_thin() M[barn_wall_x, h // 2] = C.door_closed_wooden() # Create living room: # Set initial coordinates lx_start = 1 if living_left else living_wall_x + 1 lx_end = living_wall_x - 1 if living_left else w - 1 beds_dx = int((lx_end - lx_start) % 2 == 0 and not living_left) beds_dy = random.choice([0, 1]) # Place beds near walls or at 1 cell from walls for bed_x in range(lx_start + beds_dx, lx_end, 2): M[bed_x, 1 + beds_dy].put(T.furniture_bed_single()) M[bed_x, h - 2 - beds_dy].put(T.furniture_bed_single()) # Place bonfire in the middle of the room or hearth on the side of the room is_bonfire = random.choice([True, False]) if is_bonfire: M[(lx_start + lx_end) // 2, h // 2].put(T.bonfire()) elif living_left: M[1, h // 2].put(T.furniture_hearth()) else: M[w - 2, h // 2].put(T.furniture_hearth()) # Create barn: # Set initial coordinates bx_start = 1 if not living_left else barn_wall_x + 1 bx_end = barn_wall_x - 1 if not living_left else w - 2 # Fill the barn floor with dirt for x in range(bx_start, bx_end + 1): for y in range(1, h - 1): M[x, y] = C.floor_dirt() is_central_barn = random.choice([True, False]) if is_central_barn: # Central barn: stalls in the center, two waterthroughs on the side for y in range(h // 3, h * 2 // 3): M[bx_start + 2, y] = C.wall_fence_thin() for x in range(bx_start + 3, bx_end - 2, 2): M[x, h // 2] = C.wall_fence_thin() M[x, h // 2 - 1].put(T.farm_mangler()) M[x, h // 2 + 1].put(T.farm_mangler()) for y in range(h // 3, h * 2 // 3): M[x + 1, y] = C.wall_fence_thin() for x in range(bx_start + 1, bx_end): M[x, 1].put(T.water_trough()) M[x, h - 2].put(T.water_trough()) else: # Side barn: stalls on the side, one waterthrough in the center for x in range(bx_start, bx_end - 1, 2): M[x, 1].put(T.farm_mangler()) M[x, h - 2].put(T.farm_mangler()) for y in range(1, h // 3): M[x + 1, y] = C.wall_fence_thin() for y in range(h * 2 // 3, h - 1): M[x + 1, y] = C.wall_fence_thin() for x in range(bx_start + 2, bx_end - 1): M[x, h // 2].put(T.water_trough()) # Transpose the building if it should be vertical if not is_horizontal: M.transpose() return M
def building_prison_linear(w=21, h=12, orientation='horizontal'): """ Construct a linear prison building interior. Parameters ---------- w : int Map width h : int Map height """ # Initial checks. Don't accept: # - Too small prisons # - Too wide prisons (for both horizontal and vertical orientations) if w < 11 or h < 11: raise ValueError('Building is too small: w or h < 11') if h > 16 and orientation == 'horizontal': raise ValueError( 'Building is too big: h > 16 and orientation == "horizontal"') if w > 16 and orientation == 'vertical': raise ValueError( 'Building is too big: w > 16 and orientation == "vertical"') if orientation == 'vertical': w, h = h, w M = Map(w, h, fill_cell=C.void) # Randomly choose where torture room and jailer room are. torture_left, jailer_right = None, None torture_left = random.choice([True, False]) if torture_left: jailer_right = True else: jailer_right = False # Create jailer room. We have two situations: jailer room left/right. jailer_y_start = h // 4 jailer_y_end = h // 3 * 2 if jailer_right: # Create walls, floor and door for y in range(jailer_y_start, jailer_y_end + 1): M[w - 1, y] = C.wall_stone() M[w - 5, y] = C.wall_stone() for x in range(w - 5, w): M[x, jailer_y_start] = C.wall_stone() M[x, jailer_y_end] = C.wall_stone() for y in range(jailer_y_start + 1, jailer_y_end): for x in range(w - 4, w - 1): M[x, y] = C.floor_flagged() M[w - 5, h // 2] = C.door_closed() # Place some furniture M[w - 4, jailer_y_start + 1].put(T.furniture_table()) M[w - 3, jailer_y_start + 1].put(T.furniture_table()) M[w - 2, jailer_y_start + 1].put(T.furniture_chair()) M[w - 4, jailer_y_end - 1].put(T.furniture_torch()) M[w - 3, jailer_y_end - 1].put(T.furniture_bed_single()) M[w - 2, jailer_y_end - 1].put(T.furniture_chest()) else: # Create walls, floor and door for y in range(jailer_y_start, jailer_y_end + 1): M[0, y] = C.wall_stone() M[4, y] = C.wall_stone() for x in range(0, 5): M[x, jailer_y_start] = C.wall_stone() M[x, jailer_y_end] = C.wall_stone() for y in range(jailer_y_start + 1, jailer_y_end): for x in range(1, 4): M[x, y] = C.floor_flagged() M[4, h // 2] = C.door_closed() # Place some furniture M[1, jailer_y_start + 1].put(T.furniture_table()) M[2, jailer_y_start + 1].put(T.furniture_table()) M[3, jailer_y_start + 1].put(T.furniture_chair()) M[1, jailer_y_end - 1].put(T.furniture_chest()) M[2, jailer_y_end - 1].put(T.furniture_bed_single()) M[3, jailer_y_end - 1].put(T.furniture_torch()) # Create torture room. We have two situations: torture room left/right. torture_start and torture_end - x-coord. # If torture_end = 0 or 1, there is no place for room (only one or two walls) # So we expand torture room for a one cell's width (+4) if jailer_right: torture_start = 0 torture_end = (w - 1) % 4 if torture_end == 0: torture_end = 4 if torture_end == 1: torture_end = 5 # Create walls, floor and door for x in range(torture_start, torture_end + 1): M[x, 0] = C.wall_stone() M[x, h - 1] = C.wall_stone() for y in range(0, h - 1): M[torture_start, y] = C.wall_stone() M[torture_end, y] = C.wall_stone() for x in range(torture_start + 1, torture_end): for y in range(1, h - 1): M[x, y] = C.floor_flagged() M[torture_end, h // 2] = C.door_closed() # Place some furniture. If torture_end == 2 (just a corridor), then we set only stairs. M[torture_end - 1, h - 2] = C.stairs_up() if torture_end != 2: M[(torture_end - torture_start) // 2, h // 2].put(T.furniture_torture()) all_coord = [(torture_end - 1, h - 2), ((torture_end - torture_start) // 2, h // 2)] for item_class in (T.bones, T.bones_skull, T.tool_tongs): while True: x = random.randint(1, torture_end - 1) y = random.randint(1, h - 2) if (x, y) not in all_coord: M[x, y].put(item_class()) all_coord.append((x, y)) break else: # If torture room is right, we are using the torture room width for calculations. # If torture_width = 7, then we reduce torture room for a one cell's width (-4). torture_width = w % 4 + 4 if torture_width == 7: torture_width = 3 torture_end = w - 1 # Create walls, floor and door for x in range(w - torture_width, torture_end): M[x, 0] = C.wall_stone() M[x, h - 1] = C.wall_stone() for y in range(0, h): M[w - torture_width, y] = C.wall_stone() M[torture_end, y] = C.wall_stone() for x in range(w - torture_width + 1, torture_end): for y in range(1, h - 1): M[x, y] = C.floor_flagged() M[w - torture_width, h // 2] = C.door_closed() # Place some furniture. If torture_width = 3 (just a corridor), then we set only stairs. M[w - 2, h - 2] = C.stairs_up() if torture_width != 3: M[w - 2, h // 2].put(T.furniture_torture()) all_coord = [(w - 1, h - 2), (w - 2, h // 2)] for item_class in (T.bones, T.bones_skull, T.tool_tongs): while True: x = random.randint(w - torture_width + 1, w - 2) y = random.randint(1, h - 2) if (x, y) not in all_coord: M[x, y].put(item_class()) all_coord.append((x, y)) break # Fill corridor with a floor if jailer_right: cor_start = torture_end + 1 cor_end = w - 6 else: cor_start = 5 cor_end = w - torture_width - 1 if h % 2 == 1: for x in range(cor_start, cor_end + 1): M[x, h // 2] = C.floor_flagged() else: for x in range(cor_start, cor_end + 1): M[x, h // 2 - 1] = C.floor_flagged() M[x, h // 2] = C.floor_flagged() # Place prison cells number_of_cells = (cor_end - cor_start + 2) // 4 for cell_index in range(number_of_cells): cell_x = (cor_start - 1) + (cell_index * 4) # Place upper cell M_cell = room_prison_cell(w=5, h=(h - 1) // 2) M.meld(M_cell, cell_x, 0) # Place lower cell M_cell = room_prison_cell(w=5, h=(h - 1) // 2, direction='up') M.meld(M_cell, cell_x, h // 2 + 1) if orientation == 'vertical': M.transpose() return M
def building_prison_rectangular(w=17, h=17): """ Construct a rectangular prison interior. Parameters ---------- w : int Map width h : int Map height """ # Initial checks. Don't accept too small prisons if w < 17 or h < 17: raise ValueError('Building is too small: w or h < 17') M = Map(w, h, fill_cell=C.void) # Calculate prison cells sizes depends on prison size. cell_shift_w = (w - 1) % 4 if cell_shift_w == 1: left_w = 4 right_w = 5 elif cell_shift_w == 2: left_w = 5 right_w = 5 elif cell_shift_w == 3: left_w = 5 right_w = 6 else: left_w = 4 right_w = 4 cell_shift_h = (h - 1) % 4 if cell_shift_h == 1: top_h = 4 bottom_h = 5 elif cell_shift_h == 2: top_h = 5 bottom_h = 5 elif cell_shift_h == 3: top_h = 5 bottom_h = 6 else: top_h = 4 bottom_h = 4 # Calculate the number of prison cells fits horizontally/vertically num_cell_w = (w - left_w - right_w) // 4 num_cell_h = (h - top_h - bottom_h) // 4 # Place cells for cell_index in range(num_cell_w): cell_x = left_w + (cell_index * 4) # Place upper cell M_cell = room_prison_cell(w=5, h=top_h + 1) M.meld(M_cell, cell_x, 0) # Place lower cell M_cell = room_prison_cell(w=5, h=bottom_h + 1, direction='up') M.meld(M_cell, cell_x, h - bottom_h - 1) for cell_index in range(num_cell_h): cell_y = top_h + (cell_index * 4) # Place left cell M_cell = room_prison_cell(w=left_w + 1, h=5, direction='left') M.meld(M_cell, 0, cell_y) # Place right cell M_cell = room_prison_cell(w=right_w + 1, h=5, direction='right') M.meld(M_cell, w - right_w - 1, cell_y) center_room_w = w - (left_w + 1) - (right_w + 1) - 2 center_room_h = h - (top_h + 1) - (bottom_h + 1) - 2 center_room = _room_prison_center(center_room_w, center_room_h) M.meld(center_room, left_w + 2, top_h + 2) # Construct the corridor for x in range(left_w + 1, w - right_w - 1): M[x, top_h + 1] = C.floor_flagged() M[x, h - bottom_h - 2] = C.floor_flagged() for y in range(top_h + 1, h - bottom_h - 1): M[left_w + 1, y] = C.floor_flagged() M[w - right_w - 2, y] = C.floor_flagged() return M