예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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