Example #1
0
def generateSlopeStructure(matrix,
                           height_map,
                           h_max,
                           x_min,
                           x_max,
                           z_min,
                           z_max,
                           allowStraightRails=False):
    logging.info("Trying to generate roller coaster")

    cleanProperty(matrix, height_map, h_max, x_min, x_max, z_min, z_max)
    #spawnFlowers(matrix, height_map, x_min, x_max, z_min, z_max)
    return_value = generateRollerCoaster(matrix, height_map, h_max, x_min,
                                         x_max, z_min, z_max,
                                         allowStraightRails)
    if return_value == 0:
        return 0
    slope = utilityFunctions.dotdict()
    slope.type = "rollerCoaster"
    slope.lotArea = utilityFunctions.dotdict({
        "y_min": 0,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })
    slope.buildArea = utilityFunctions.dotdict({
        "y_min": 0,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })
    slope.orientation = getOrientation()
    slope.entranceLot = (height_map[x_min][z_min], slope.lotArea.x_min,
                         slope.lotArea.z_min)
    return slope
Example #2
0
def generateHouse(matrix, h_min, h_max, x_min, x_max, z_min, z_max, biome,
                  usable_wood):

    house = utilityFunctions.dotdict()
    house.type = "house"
    house.lotArea = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })

    #generateFence(matrix, h_min, x_min, x_max, z_min, z_max)

    (h_min, h_max, x_min, x_max, z_min,
     z_max) = getHouseAreaInsideLot(h_min, h_max, x_min, x_max, z_min, z_max)
    # calculate the top height of the walls, i.e. where the first
    # row of blocks of the pitched roof will be placed
    ceiling_bottom = h_max - int((h_max - h_min) * 0.5)
    house.buildArea = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": ceiling_bottom,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })

    logging.info("Generating house at area {}".format(house.lotArea))
    logging.info("Construction area {}".format(house.buildArea))
    utilityFunctions.cleanProperty2(matrix, house.lotArea.y_min + 1,
                                    house.lotArea.y_max, x_min - 1, x_max + 1,
                                    z_min - 1, z_max + 1)

    picked_wood = utilityFunctions.selectRandomWood(usable_wood)
    floor = BlocksInfo.getHouseFloorId(biome, picked_wood)
    wall = BlocksInfo.getHouseWallId(biome)
    wall = BlocksInfo.getPlankId(picked_wood) if wall[0] == -1 else wall
    pillar = BlocksInfo.getHousePillarId(wall, picked_wood)
    ceiling = BlocksInfo.getStairsId(biome, picked_wood)
    roof = BlocksInfo.getStructureBlockId(biome, picked_wood)
    pavement_block = BlocksInfo.getPavmentId(biome)

    house.orientation = getOrientation(matrix, house.lotArea)
    window_y = house.buildArea.y_min + 3
    door_y = house.buildArea.y_min + 1

    if house.orientation == "N":
        door_x = RNG.randint(house.buildArea.x_min + 4,
                             house.buildArea.x_max - 4)
        door_z = house.buildArea.z_min
        utilityFunctions.cleanProperty2(matrix, h_min + 1, h_max, door_x - 1,
                                        door_x + 1, house.lotArea.z_min + 1,
                                        z_min - 1)
        # generate walls from x_min+1, x_max-1, etc to leave space for the roof
        generateWalls(matrix, house.buildArea.y_min, house.buildArea.y_max,
                      house.buildArea.x_min, house.buildArea.x_max,
                      house.buildArea.z_min, house.buildArea.z_max, wall,
                      pillar)
        generateFloor(matrix, house.buildArea.y_min, house.buildArea.x_min,
                      house.buildArea.x_max, house.buildArea.z_min,
                      house.buildArea.z_max, floor)
        generateDoor(matrix, door_y, door_x, door_z, (64, 9), (64, 1))
        house.entranceLot = (h_min + 1, door_x, house.lotArea.z_min)
        # entrance path
        for z in range(house.lotArea.z_min, door_z):
            matrix.setValue(h_min, door_x, z, pavement_block)
            matrix.setValue(h_min, door_x - 1, z, pavement_block)
            matrix.setValue(h_min, door_x + 1, z, pavement_block)

    elif house.orientation == "S":
        door_x = RNG.randint(house.buildArea.x_min + 4,
                             house.buildArea.x_max - 4)
        door_z = house.buildArea.z_max
        utilityFunctions.cleanProperty2(matrix, h_min + 1, h_max, door_x - 1,
                                        door_x + 1, z_max + 1,
                                        house.lotArea.z_max - 1)
        # generate walls from x_min+1, x_max-1, etc to leave space for the roof
        generateWalls(matrix, house.buildArea.y_min, house.buildArea.y_max,
                      house.buildArea.x_min, house.buildArea.x_max,
                      house.buildArea.z_min, house.buildArea.z_max, wall,
                      pillar)
        generateFloor(matrix, house.buildArea.y_min, house.buildArea.x_min,
                      house.buildArea.x_max, house.buildArea.z_min,
                      house.buildArea.z_max, floor)
        generateDoor(matrix, door_y, door_x, door_z, (64, 9), (64, 3))
        house.entranceLot = (h_min + 1, door_x, house.lotArea.z_max)
        # entrance path
        for z in range(door_z + 1, house.lotArea.z_max):
            matrix.setValue(h_min, door_x, z, pavement_block)
            matrix.setValue(h_min, door_x - 1, z, pavement_block)
            matrix.setValue(h_min, door_x + 1, z, pavement_block)

    elif house.orientation == "W":
        door_x = house.buildArea.x_min
        door_z = RNG.randint(house.buildArea.z_min + 4,
                             house.buildArea.z_max - 4)
        utilityFunctions.cleanProperty2(matrix, h_min + 1, h_max,
                                        house.lotArea.x_min + 1, x_min - 1,
                                        door_z - 1, door_z + 1)
        # generate walls from x_min+1, x_max-1, etc to leave space for the roof
        generateWalls(matrix, house.buildArea.y_min, house.buildArea.y_max,
                      house.buildArea.x_min, house.buildArea.x_max,
                      house.buildArea.z_min, house.buildArea.z_max, wall,
                      pillar)
        generateFloor(matrix, house.buildArea.y_min, house.buildArea.x_min,
                      house.buildArea.x_max, house.buildArea.z_min,
                      house.buildArea.z_max, floor)
        generateDoor(matrix, door_y, door_x, door_z, (64, 8), (64, 0))
        house.entranceLot = (h_min + 1, house.lotArea.x_min, door_z)
        # entrance path
        for x in range(house.lotArea.x_min, door_x):
            matrix.setValue(h_min, x, door_z, pavement_block)
            matrix.setValue(h_min, x, door_z - 1, pavement_block)
            matrix.setValue(h_min, x, door_z + 1, pavement_block)

    elif house.orientation == "E":
        door_x = house.buildArea.x_max
        door_z = RNG.randint(house.buildArea.z_min + 4,
                             house.buildArea.z_max - 4)
        utilityFunctions.cleanProperty2(matrix, h_min + 1, h_max, x_max + 1,
                                        house.lotArea.x_max - 1, door_z - 1,
                                        door_z + 1)
        # generate walls from x_min+1, x_max-1, etc to leave space for the roof
        generateWalls(matrix, house.buildArea.y_min, house.buildArea.y_max,
                      house.buildArea.x_min, house.buildArea.x_max,
                      house.buildArea.z_min, house.buildArea.z_max, wall,
                      pillar)
        generateFloor(matrix, house.buildArea.y_min, house.buildArea.x_min,
                      house.buildArea.x_max, house.buildArea.z_min,
                      house.buildArea.z_max, floor)
        generateDoor(matrix, door_y, door_x, door_z, (64, 9), (64, 2))
        house.entranceLot = (h_min + 1, house.lotArea.x_max, door_z)
        # entrance path
        for x in range(door_x + 1, house.lotArea.x_max + 1):
            matrix.setValue(h_min, x, door_z, pavement_block)
            matrix.setValue(h_min, x, door_z - 1, pavement_block)
            matrix.setValue(h_min, x, door_z + 1, pavement_block)

    if house.orientation == "N" or house.orientation == "S":
        generateWindow_alongX(matrix, window_y, house.buildArea.x_min,
                              house.buildArea.z_min, house.buildArea.z_max)
        generateWindow_alongX(matrix, window_y, house.buildArea.x_max,
                              house.buildArea.z_min, house.buildArea.z_max)
        generateCeiling_x(matrix, ceiling_bottom, h_max, x_min - 1, x_max + 1,
                          z_min - 1, z_max + 1, ceiling[0], roof, wall, 0)
    elif house.orientation == "E" or house.orientation == "W":
        generateWindow_alongZ(matrix, window_y, house.buildArea.z_min,
                              house.buildArea.x_min, house.buildArea.x_max)
        generateWindow_alongZ(matrix, window_y, house.buildArea.z_max,
                              house.buildArea.x_min, house.buildArea.x_max)
        generateCeiling_z(matrix, ceiling_bottom, h_max, x_min - 1, x_max + 1,
                          z_min - 1, z_max + 1, ceiling[0], roof, wall, 0)

    generateInterior(matrix, h_min, ceiling_bottom, house.buildArea.x_min,
                     house.buildArea.x_max, house.buildArea.z_min,
                     house.buildArea.z_max, picked_wood, biome)

    return house
Example #3
0
def generateTower(matrix, x_min, x_max, z_min, z_max, height_map):

    tower = utilityFunctions.dotdict()
    tower.type = "tower"

    (h_tower, min_h, max_h, x_min, x_max, z_min,
     z_max) = getTowerAreaInsideLot(x_min, x_max, z_min, z_max, height_map)

    tower.buildArea = utilityFunctions.dotdict({
        "y_min": min_h,
        "y_max": h_tower,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })
    (door_pos, door_y,
     tower.orientation) = getOrientationT(matrix, tower.buildArea, height_map)
    cleanTowerArea(matrix, door_y - 1, h_tower + 3, x_min, x_max, z_min, z_max)

    logging.info("Generating tower at area {}".format(tower.buildArea))

    wall = (45, 0)
    floor = wall

    generateWalls(matrix, min_h + 1, h_tower, x_min, x_max, z_min, z_max, wall)
    generateCeiling(matrix, h_tower, x_min, x_max, z_min, z_max)

    if tower.orientation == "N":
        door_x = door_pos[0]
        door_z = door_pos[1]
        generateDoor(matrix, door_y, door_x, door_z, (64, 9), (64, 1))
        tower.entranceLot = (door_x, door_z - 1)
        matrix.setValue(door_y - 1, door_x, door_z - 1, (1, 6))

    elif tower.orientation == "S":
        door_x = door_pos[0]
        door_z = door_pos[1]
        generateDoor(matrix, door_y, door_x, door_z, (64, 9), (64, 3))
        tower.entranceLot = (door_x, door_z + 1)
        matrix.setValue(door_y - 1, door_x, door_z + 1, (1, 6))

    elif tower.orientation == "W":
        door_x = door_pos[0]
        door_z = door_pos[1]
        generateDoor(matrix, door_y, door_x, door_z, (64, 8), (64, 0))
        tower.entranceLot = (door_x - 1, door_z)
        matrix.setValue(door_y - 1, door_x - 1, door_z, (1, 6))

    elif tower.orientation == "E":
        door_x = door_pos[0]
        door_z = door_pos[1]
        generateDoor(matrix, door_y, door_x, door_z, (64, 9), (64, 2))
        tower.entranceLot = (door_x + 1, door_z)
        matrix.setValue(door_y - 1, door_x + 1, door_z, (1, 6))

    generateFloor(matrix, door_y - 1, x_min, x_max, z_min, z_max, floor)
    generateInside(matrix, door_y, h_tower, x_min, x_max, z_min, z_max,
                   tower.orientation)

    return tower
Example #4
0
def generateHouse(matrix,
                  h_min,
                  h_max,
                  x_min,
                  x_max,
                  z_min,
                  z_max,
                  ceiling=None):

    house = utilityFunctions.dotdict()
    house.type = "house"
    house.lotArea = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })

    utilityFunctions.cleanProperty(matrix, h_min + 1, h_max, x_min, x_max,
                                   z_min, z_max)
    #generateFence(matrix, h_min, x_min, x_max, z_min, z_max)

    (h_min, h_max, x_min, x_max, z_min,
     z_max) = getHouseAreaInsideLot(h_min, h_max, x_min, x_max, z_min, z_max)
    # calculate the top height of the walls, i.e. where the first
    # row of blocks of the pitched roof will be placed
    ceiling_bottom = h_max - int((h_max - h_min) * 0.5)
    house.buildArea = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": ceiling_bottom,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })

    logging.info("Generating house at area {}".format(house.lotArea))
    logging.info("Construction area {}".format(house.buildArea))

    wall = (43, RNG.randint(11, 15))
    ceiling = (5, RNG.randint(1, 5)) if ceiling == None else ceiling
    floor = wall

    # generate walls from x_min+1, x_max-1, etc to leave space for the roof
    generateWalls(matrix, house.buildArea.y_min, house.buildArea.y_max,
                  house.buildArea.x_min, house.buildArea.x_max,
                  house.buildArea.z_min, house.buildArea.z_max, wall)
    generateFloor(matrix, house.buildArea.y_min, house.buildArea.x_min,
                  house.buildArea.x_max, house.buildArea.z_min,
                  house.buildArea.z_max, floor)

    house.orientation = getOrientation(matrix, house.lotArea)
    window_y = house.buildArea.y_min + 3
    door_y = house.buildArea.y_min + 1

    if house.orientation == "N":
        door_x = RNG.randint(house.buildArea.x_min + 4,
                             house.buildArea.x_max - 4)
        door_z = house.buildArea.z_min
        generateDoor(matrix, door_y, door_x, door_z, (64, 9), (64, 1))
        house.entranceLot = (h_min + 1, door_x, house.lotArea.z_min)
        # entrance path
        for z in range(house.lotArea.z_min, door_z):
            matrix.setValue(h_min, door_x, z, (4, 0))
            matrix.setValue(h_min, door_x - 1, z, (4, 0))
            matrix.setValue(h_min, door_x + 1, z, (4, 0))

    elif house.orientation == "S":
        door_x = RNG.randint(house.buildArea.x_min + 4,
                             house.buildArea.x_max - 4)
        door_z = house.buildArea.z_max
        generateDoor(matrix, door_y, door_x, door_z, (64, 9), (64, 3))
        house.entranceLot = (h_min + 1, door_x, house.lotArea.z_max)
        # entrance path
        for z in range(door_z + 1, house.lotArea.z_max):
            matrix.setValue(h_min, door_x, z, (4, 0))
            matrix.setValue(h_min, door_x - 1, z, (4, 0))
            matrix.setValue(h_min, door_x + 1, z, (4, 0))

    elif house.orientation == "W":
        door_x = house.buildArea.x_min
        door_z = RNG.randint(house.buildArea.z_min + 4,
                             house.buildArea.z_max - 4)
        generateDoor(matrix, door_y, door_x, door_z, (64, 8), (64, 0))
        house.entranceLot = (h_min + 1, house.lotArea.x_min, door_z)
        # entrance path
        for x in range(house.lotArea.x_min, door_x):
            matrix.setValue(h_min, x, door_z, (4, 0))
            matrix.setValue(h_min, x, door_z - 1, (4, 0))
            matrix.setValue(h_min, x, door_z + 1, (4, 0))

    elif house.orientation == "E":
        door_x = house.buildArea.x_max
        door_z = RNG.randint(house.buildArea.z_min + 4,
                             house.buildArea.z_max - 4)
        generateDoor(matrix, door_y, door_x, door_z, (64, 9), (64, 2))
        house.entranceLot = (h_min + 1, house.lotArea.x_max, door_z)
        # entrance path
        for x in range(door_x + 1, house.lotArea.x_max + 1):
            matrix.setValue(h_min, x, door_z, (4, 0))
            matrix.setValue(h_min, x, door_z - 1, (4, 0))
            matrix.setValue(h_min, x, door_z + 1, (4, 0))

    if house.orientation == "N" or house.orientation == "S":
        generateWindow_alongX(matrix, window_y, house.buildArea.x_min,
                              house.buildArea.z_min, house.buildArea.z_max)
        generateWindow_alongX(matrix, window_y, house.buildArea.x_max,
                              house.buildArea.z_min, house.buildArea.z_max)
        generateCeiling_x(matrix, ceiling_bottom, h_max, x_min - 1, x_max + 1,
                          z_min - 1, z_max + 1, ceiling, wall, 0)
    elif house.orientation == "E" or house.orientation == "W":
        generateWindow_alongZ(matrix, window_y, house.buildArea.z_min,
                              house.buildArea.x_min, house.buildArea.x_max)
        generateWindow_alongZ(matrix, window_y, house.buildArea.z_max,
                              house.buildArea.x_min, house.buildArea.x_max)
        generateCeiling_z(matrix, ceiling_bottom, h_max, x_min - 1, x_max + 1,
                          z_min - 1, z_max + 1, ceiling, wall, 0)

    generateInterior(matrix, h_min, ceiling_bottom, house.buildArea.x_min,
                     house.buildArea.x_max, house.buildArea.z_min,
                     house.buildArea.z_max, ceiling)

    return house
def perform(level, box, options):
    logging.info("BoundingBox coordinates: ({},{}),({},{}),({},{})".format(
        box.miny, box.maxy, box.minx, box.maxx, box.minz, box.maxz))

    # ==== PREPARATION =====
    logging.info("Preparation")
    (width, height, depth) = utilityFunctions.getBoxSize(box)
    logging.info("Selection box dimensions {}, {}, {}".format(
        width, height, depth))
    world = utilityFunctions.generateMatrix(level, box, width, depth, height)
    world_space = utilityFunctions.dotdict({
        "y_min": 0,
        "y_max": height - 1,
        "x_min": 0,
        "x_max": width - 1,
        "z_min": 0,
        "z_max": depth - 1
    })
    logging.info("Generating simple height map")
    simple_height_map = utilityFunctions.getSimpleHeightMap(
        level, box)  #no height = -1 when water like block
    logging.info("Saving and erasing the trees")
    list_trees = TreeGestion.prepareMap(
        world, simple_height_map
    )  #get a list of all trees and erase them, so we can put some of them back after
    logging.info("Generating normal height map")
    height_map = utilityFunctions.getHeightMap(level, box)
    #villageDeck = utilityFunctions.generateVillageDeck("city", width, depth)

    # ==== PARTITIONING OF NEIGHBOURHOODS ====
    logging.info(
        "Partitioning of the map, getting city center and neighbourhoods")
    (center,
     neighbourhoods) = generateCenterAndNeighbourhood(world_space, height_map)
    all_buildings = []

    # ====  GENERATING CITY CENTER ====
    logging.info("Generating city center")
    minimum_h = 50
    minimum_w = 25
    mininum_d = 25

    iterate = 100
    minimum_lots = 6
    available_lots = 0
    maximum_tries = 50
    current_try = 0
    threshold = 20
    partitioning_list = []
    temp_partitioning_list = []

    # run the partitioning algorithm for iterate times to get different partitionings of the same area
    logging.info(
        "Generating {} different partitionings for the the City Centre {}".
        format(iterate, center))
    while available_lots < minimum_lots and current_try < maximum_tries:

        for i in range(iterate):

            # generate a partitioning through some algorithm
            if RNG.random() < 0.5:
                partitioning = binarySpacePartitioning(center[0], center[1],
                                                       center[2], center[3],
                                                       center[4], center[5],
                                                       [])
            else:
                partitioning = quadtreeSpacePartitioning(
                    center[0], center[1], center[2], center[3], center[4],
                    center[5], [])

            # remove invalid partitions from the partitioning
            valid_partitioning = []
            for p in partitioning:
                (y_min, y_max, x_min, x_max, z_min, z_max) = (p[0], p[1], p[2],
                                                              p[3], p[4], p[5])
                failed_conditions = []
                cond1 = utilityFunctions.hasValidGroundBlocks(
                    x_min, x_max, z_min, z_max, height_map)
                if cond1 == False: failed_conditions.append(1)
                cond2 = utilityFunctions.hasMinimumSize(
                    y_min, y_max, x_min, x_max, z_min, z_max, minimum_h,
                    minimum_w, mininum_d)
                if cond2 == False: failed_conditions.append(2)
                cond3 = utilityFunctions.hasAcceptableSteepness(
                    x_min, x_max, z_min, z_max, height_map,
                    utilityFunctions.getScoreArea_type4, threshold)
                if cond3 == False: failed_conditions.append(3)
                if cond1 and cond2 and cond3:
                    score = utilityFunctions.getScoreArea_type4(
                        height_map, x_min, x_max, z_min, z_max)
                    valid_partitioning.append((score, p))
                    logging.info("Passed the 3 conditions!")
                else:
                    logging.info(
                        "Failed Conditions {}".format(failed_conditions))

            partitioning_list.extend(valid_partitioning)
            logging.info(
                "Generated a partition with {} valid lots and {} invalids ones"
                .format(len(valid_partitioning),
                        len(partitioning) - len(valid_partitioning)))

        # order partitions by steepness
        partitioning_list = sorted(partitioning_list)
        final_partitioning = utilityFunctions.getNonIntersectingPartitions(
            partitioning_list)

        available_lots = len(final_partitioning)
        logging.info(
            "Current partitioning with most available_lots: {}, current threshold {}"
            .format(available_lots, threshold))

        threshold += 2
        current_try += 1

    logging.info("Final lots ({}) for the City Centre {}: ".format(
        len(final_partitioning), center))
    for p in final_partitioning:
        logging.info("\t{}".format(p))

    for partition in final_partitioning:
        building = generateBuilding(world, partition, height_map,
                                    simple_height_map)
        all_buildings.append(building)

    # ==== GENERATING NEIGHBOURHOODS ====
    logging.info("Generating neighbourhoods")
    minimum_h = 10
    minimum_w = 16
    mininum_d = 16

    iterate = 100
    maximum_tries = 80
    current_try = 0
    minimum_lots = 50
    available_lots = 0
    threshold = 50
    partitioning_list = []
    final_partitioning = []

    while available_lots < minimum_lots and current_try < maximum_tries:
        partitioning_list = []
        for i in range(iterate):
            for neigh in neighbourhoods:
                logging.info(
                    "Generating {} different partitionings for the neighbourhood {}"
                    .format(iterate, neigh))

                if RNG.random() < 0.5:
                    partitioning = binarySpacePartitioning(
                        neigh[0], neigh[1], neigh[2], neigh[3], neigh[4],
                        neigh[5], [])
                else:
                    partitioning = quadtreeSpacePartitioning(
                        neigh[0], neigh[1], neigh[2], neigh[3], neigh[4],
                        neigh[5], [])

                valid_partitioning = []
                for p in partitioning:
                    (y_min, y_max, x_min, x_max, z_min,
                     z_max) = (p[0], p[1], p[2], p[3], p[4], p[5])
                    failed_conditions = []
                    cond1 = utilityFunctions.hasValidGroundBlocks(
                        x_min, x_max, z_min, z_max, height_map)
                    if cond1 == False: failed_conditions.append(1)
                    cond2 = utilityFunctions.hasMinimumSize(
                        y_min, y_max, x_min, x_max, z_min, z_max, minimum_h,
                        minimum_w, mininum_d)
                    if cond2 == False: failed_conditions.append(2)
                    cond3 = utilityFunctions.hasAcceptableSteepness(
                        x_min, x_max, z_min, z_max, height_map,
                        utilityFunctions.getScoreArea_type4, threshold)
                    if cond3 == False: failed_conditions.append(3)
                    if cond1 and cond2 and cond3:
                        score = utilityFunctions.getScoreArea_type4(
                            height_map, x_min, x_max, z_min, z_max)
                        valid_partitioning.append((score, p))
                        logging.info("Passed the 3 conditions!")
                    else:
                        logging.info(
                            "Failed Conditions {}".format(failed_conditions))

                partitioning_list.extend(valid_partitioning)
                logging.info(
                    "Generated a partition with {} valid lots and {} invalids ones"
                    .format(len(valid_partitioning),
                            len(partitioning) - len(valid_partitioning)))

        temp_partitioning_list.extend(partitioning_list)
        # order partitions by steepness
        temp_partitioning_list = sorted(temp_partitioning_list)
        final_partitioning = utilityFunctions.getNonIntersectingPartitions(
            temp_partitioning_list)

        available_lots = len(final_partitioning)
        logging.info(
            "Current neighbourhood partitioning with most available_lots: {}, current threshold {}"
            .format(available_lots, threshold))

        threshold += 2
        current_try += 1

        logging.info("Final lots ({})for the neighbourhood {}: ".format(
            len(final_partitioning), neigh))
        for p in final_partitioning:
            logging.info("\t{}".format(p))

    logging.info("Building in the neighbourhood")
    n = 0
    for i in xrange(0, int(len(final_partitioning) * 0.50) + 1):
        house = generateHouse(world, final_partitioning[i], height_map,
                              simple_height_map)
        all_buildings.append(house)
        logging.info("House number : {} built on lot number {}".format(
            n + 1, i + 1))
        n += 1
    n = 0
    for i in xrange(
            int(len(final_partitioning) * 0.50) + 1,
            int(len(final_partitioning) * 0.70) + 1):
        # generate either a regular farm or a smiley farm
        farm = generateFarm(world, final_partitioning[i],
                            height_map, simple_height_map) if (RNG.randint(
                                0, 2) == 0) else generateFarm(
                                    world, final_partitioning[i], height_map,
                                    simple_height_map, "smiley")
        all_buildings.append(farm)
        logging.info("Farm number : {} built on lot number {}".format(
            n + 1, i + 1))
        n += 1
    n = 0
    m = 0
    for i in xrange(
            int(len(final_partitioning) * 0.70) + 1, len(final_partitioning)):
        slopeStructure = generateSlopeStructure(world, final_partitioning[i],
                                                height_map, simple_height_map)
        if slopeStructure.type == "tower":
            all_buildings.append(slopeStructure)
            logging.info("Tower number : {} built on lot number {}".format(
                n + 1, i + 1))
            n += 1
        else:
            logging.info(
                "RollerCoaster number : {} built on lot number {}".format(
                    m + 1, i + 1))
            m += 1

    # ==== GENERATE PATH MAP  ====
    # generate a path map that gives the cost of moving to each neighbouring cell
    logging.info("Generating path map and simple path map")
    pathMap = utilityFunctions.getPathMap(height_map, width, depth)
    simple_pathMap = utilityFunctions.getPathMap(simple_height_map, width,
                                                 depth)  #not affected by water

    # ==== CONNECTING BUILDINGS WITH ROADS  ====
    logging.info("Calling MST on {} buildings".format(len(all_buildings)))
    MST = utilityFunctions.getMST_Manhattan(all_buildings)

    for m in MST:
        p1 = m[1]
        p2 = m[2]
        if p1.type == "farm" or p2.type == "farm":
            pavement_Type = "Grass"
            bridge_Type = "Wood"
        else:
            pavement_Type = "Stone"
            bridge_Type = "Stone"

        try:
            logging.info(
                "Trying to find a path between {} and {}, finding potential bridges"
                .format(p1.entranceLot, p2.entranceLot))
            simple_path = utilityFunctions.simpleAStar(
                p1.entranceLot, p2.entranceLot, simple_pathMap,
                simple_height_map)  #water and height are not important
            list_end_points = utilityFunctions.findBridgeEndPoints(
                world, simple_path, simple_height_map)

            if list_end_points != []:
                for i in xrange(0, len(list_end_points), 2):
                    logging.info(
                        "Found water between {} and {}. Trying to generating a {} bridge..."
                        .format(list_end_points[i], list_end_points[i + 1],
                                bridge_Type))
                    GenerateBridge.generateBridge(world, simple_height_map,
                                                  list_end_points[i],
                                                  list_end_points[i + 1],
                                                  bridge_Type)
                list_end_points.insert(0, p1.entranceLot)
                list_end_points.append(p2.entranceLot)
                for i in xrange(0, len(list_end_points), 2):
                    path = utilityFunctions.aStar(list_end_points[i],
                                                  list_end_points[i + 1],
                                                  pathMap, height_map)
                    logging.info(
                        "Connecting end points of the bridge(s), Generating {} road between {} and {}"
                        .format(pavement_Type, list_end_points[i],
                                list_end_points[i + 1]))
                    GeneratePath.generatePath(world, path, height_map,
                                              pavement_Type)
            else:
                logging.info(
                    "No potential bridge found, Generating road between {} and {}"
                    .format(list_end_points[i], list_end_points[i + 1]))
                GeneratePath.generatePath(world, simple_path, height_map,
                                          pavement_Type)

        except:
            logging.info(
                "Bridge found but is not buildable, Trying to find a path between {} and {} avoiding water"
                .format(p1.entranceLot, p2.entranceLot))
            path = utilityFunctions.aStar(p1.entranceLot, p2.entranceLot,
                                          pathMap, height_map)
            if path != None:
                logging.info(
                    "Path found, Generating {} road between {} and {}".format(
                        pavement_Type, p1.entranceLot, p2.entranceLot))
                GeneratePath.generatePath(world, path, height_map,
                                          pavement_Type)
            else:
                logging.info(
                    "Couldnt find path between {} and {}. Generating a straight road"
                    .format(p1.entranceLot, p2.entranceLot))
                GeneratePath.generatePath_StraightLine(
                    world, p1.entranceLot[1], p1.entranceLot[2],
                    p2.entranceLot[1], p2.entranceLot[2], height_map,
                    pavement_Type)

    # ==== PUT BACK UNTOUCHED TREES ====
    logging.info("Putting back untouched trees")
    TreeGestion.putBackTrees(
        world, height_map, list_trees
    )  #put back the trees that are not cut buy the building and are not in unwanted places

    # ==== UPDATE WORLD ====
    world.updateWorld()
def perform(level, box, options):

    logging.info("BoundingBox coordinates: ({},{}),({},{}),({},{})".format(
        box.miny, box.maxy, box.minx, box.maxx, box.minz, box.maxz))

    # ==== PREPARATION =====
    (width, height, depth) = utilityFunctions.getBoxSize(box)
    logging.info("Selection box dimensions {}, {}, {}".format(
        width, height, depth))
    world = utilityFunctions.generateMatrix(level, box, width, depth, height)
    world_space = utilityFunctions.dotdict({
        "y_min": 0,
        "y_max": height - 1,
        "x_min": 0,
        "x_max": width - 1,
        "z_min": 0,
        "z_max": depth - 1
    })
    height_map = utilityFunctions.getHeightMap(level, box)

    # ==== PARTITIONING OF NEIGHBOURHOODS ====
    (center,
     neighbourhoods) = generateCenterAndNeighbourhood(world_space, height_map)
    all_buildings = []

    # ====  GENERATING CITY CENTER ====
    minimum_h = 50
    minimum_w = 25
    mininum_d = 25

    iterate = 100
    minimum_lots = 6
    available_lots = 0
    maximum_tries = 50
    current_try = 0
    threshold = 1
    partitioning_list = []
    temp_partitioning_list = []

    # run the partitioning algorithm for iterate times to get different partitionings of the same area
    logging.info(
        "Generating {} different partitionings for the the City Centre {}".
        format(iterate, center))
    while available_lots < minimum_lots and current_try < maximum_tries:

        for i in range(iterate):

            # generate a partitioning through some algorithm
            if RNG.random() < 0.5:
                partitioning = binarySpacePartitioning(center[0], center[1],
                                                       center[2], center[3],
                                                       center[4], center[5],
                                                       [])
            else:
                partitioning = quadtreeSpacePartitioning(
                    center[0], center[1], center[2], center[3], center[4],
                    center[5], [])

            # remove invalid partitions from the partitioning
            valid_partitioning = []
            for p in partitioning:
                (y_min, y_max, x_min, x_max, z_min, z_max) = (p[0], p[1], p[2],
                                                              p[3], p[4], p[5])
                failed_conditions = []
                cond1 = utilityFunctions.hasValidGroundBlocks(
                    x_min, x_max, z_min, z_max, height_map)
                if cond1 == False: failed_conditions.append(1)
                cond2 = utilityFunctions.hasMinimumSize(
                    y_min, y_max, x_min, x_max, z_min, z_max, minimum_h,
                    minimum_w, mininum_d)
                if cond2 == False: failed_conditions.append(2)
                cond3 = utilityFunctions.hasAcceptableSteepness(
                    x_min, x_max, z_min, z_max, height_map,
                    utilityFunctions.getScoreArea_type1, threshold)
                if cond3 == False: failed_conditions.append(3)
                if cond1 and cond2 and cond3:
                    score = utilityFunctions.getScoreArea_type1(
                        height_map, x_min, x_max, z_min, z_max)
                    valid_partitioning.append((score, p))
                else:
                    logging.info(
                        "Failed Conditions {}".format(failed_conditions))

            partitioning_list.extend(valid_partitioning)
            logging.info(
                "Generated a partition with {} valid lots and {} invalids ones"
                .format(len(valid_partitioning),
                        len(partitioning) - len(valid_partitioning)))

        # order partitions by steepness
        partitioning_list = sorted(partitioning_list)
        final_partitioning = utilityFunctions.getNonIntersectingPartitions(
            partitioning_list)

        available_lots = len(final_partitioning)
        logging.info(
            "Current partitioning with most available_lots: {}, current threshold {}"
            .format(available_lots, threshold))

        threshold += 1
        current_try += 1

    logging.info("Final lots ({}) for the City Centre {}: ".format(
        len(final_partitioning), center))
    for p in final_partitioning:
        logging.info("\t{}".format(p))

    for partition in final_partitioning:
        building = generateBuilding(world, partition, height_map)
        all_buildings.append(building)

    # ==== GENERATING NEIGHBOURHOODS ====

    minimum_h = 3
    minimum_w = 7
    mininum_d = 6

    iterate = 100
    maximum_tries = 50
    current_try = 0
    minimum_lots = 20
    available_lots = 0
    threshold = 1
    partitioning_list = []
    final_partitioning = []

    while available_lots < minimum_lots and current_try < maximum_tries:
        partitioning_list = []
        for i in range(iterate):
            for neigh in neighbourhoods:
                logging.info(
                    "Generating {} different partitionings for the neighbourhood {}"
                    .format(iterate, neigh))

                if RNG.random() < 0.5:
                    partitioning = binarySpacePartitioning(
                        neigh[0], neigh[1], neigh[2], neigh[3], neigh[4],
                        neigh[5], [])
                else:
                    partitioning = quadtreeSpacePartitioning(
                        neigh[0], neigh[1], neigh[2], neigh[3], neigh[4],
                        neigh[5], [])

                valid_partitioning = []
                for p in partitioning:
                    (y_min, y_max, x_min, x_max, z_min,
                     z_max) = (p[0], p[1], p[2], p[3], p[4], p[5])
                    failed_conditions = []
                    cond1 = utilityFunctions.hasValidGroundBlocks(
                        x_min, x_max, z_min, z_max, height_map)
                    if cond1 == False: failed_conditions.append(1)
                    cond2 = utilityFunctions.hasMinimumSize(
                        y_min, y_max, x_min, x_max, z_min, z_max, minimum_h,
                        minimum_w, mininum_d)
                    if cond2 == False: failed_conditions.append(2)
                    cond3 = utilityFunctions.hasAcceptableSteepness(
                        x_min, x_max, z_min, z_max, height_map,
                        utilityFunctions.getScoreArea_type1, threshold)
                    if cond3 == False: failed_conditions.append(3)
                    if cond1 and cond2 and cond3:
                        score = utilityFunctions.getScoreArea_type1(
                            height_map, x_min, x_max, z_min, z_max)
                        valid_partitioning.append((score, p))
                        logging.info("Passed the 3 conditions!")
                    else:
                        logging.info(
                            "Failed Conditions {}".format(failed_conditions))

                partitioning_list.extend(valid_partitioning)
                logging.info(
                    "Generated a partition with {} valid lots and {} invalids ones"
                    .format(len(valid_partitioning),
                            len(partitioning) - len(valid_partitioning)))

        temp_partitioning_list.extend(partitioning_list)
        # order partitions by steepness
        temp_partitioning_list = sorted(temp_partitioning_list)
        final_partitioning = utilityFunctions.getNonIntersectingPartitions(
            temp_partitioning_list)

        available_lots = len(final_partitioning)
        logging.info(
            "Current neighbourhood partitioning with most available_lots: {}, current threshold {}"
            .format(available_lots, threshold))

        threshold += 1
        current_try += 1

        logging.info("Final lots ({})for the neighbourhood {}: ".format(
            len(final_partitioning), neigh))
        for p in final_partitioning:
            logging.info("\t{}".format(p))

    for partition in final_partitioning:
        house = generateHouse(world, partition, height_map)
        all_buildings.append(house)

    # ==== GENERATE PATH MAP  ====
    # generate a path map that gives the cost of moving to each neighbouring cell
    pathMap = utilityFunctions.getPathMap(height_map, width, depth)

    # ==== CONNECTING BUILDINGS WITH ROADS  ====
    logging.info("Calling MST on {} buildings".format(len(all_buildings)))
    MST = utilityFunctions.getMST_Manhattan(all_buildings, pathMap, height_map)

    pavementBlockID = 4
    pavementBlockSubtype = 0
    for m in MST:
        p1 = m[1]
        p2 = m[2]
        logging.info("Pavement with distance {} between {} and {}".format(
            m[0], p1.entranceLot, p2.entranceLot))

        path = utilityFunctions.aStar(p1.entranceLot, p2.entranceLot, pathMap,
                                      height_map)
        if path != None:
            logging.info(
                "Found path between {} and {}. Generating road...".format(
                    p1.entranceLot, p2.entranceLot))
            GeneratePath.generatPath(world, path, height_map,
                                     (pavementBlockID, pavementBlockSubtype))
        else:
            logging.info(
                "Couldnt find path between {} and {}. Generating a straight road between them..."
                .format(p1.entranceLot, p2.entranceLot))
            GeneratePath.generatPath_StraightLine(
                world, p1.entranceLot[1], p1.entranceLot[2], p2.entranceLot[1],
                p2.entranceLot[2], height_map,
                (pavementBlockID, pavementBlockSubtype))

    # ==== UPDATE WORLD ====
    world.updateWorld()
Example #7
0
def generateBuilding(matrix, h_min, h_max, x_min, x_max, z_min, z_max):

    building = utilityFunctions.dotdict()
    building.type = "building"

    building.lotArea = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })

    utilityFunctions.cleanProperty(matrix, h_min + 1, h_max, x_min, x_max,
                                   z_min, z_max)

    (h_min, h_max, x_min, x_max, z_min,
     z_max) = getBuildingAreaInsideLot(h_min, h_max, x_min, x_max, z_min,
                                       z_max)
    building.buildArea = (h_min, h_max, x_min, x_max, z_min, z_max)

    logging.info("Generating building at area {}".format(building.lotArea))
    logging.info("Construction area {}".format(building.buildArea))

    wall = (159, random.randint(0, 15))
    ceiling = wall
    floor = wall

    floor_size = 8
    max_height = h_max - h_min
    if max_height > 32:
        h_max = h_min + random.randint(32,
                                       80 if max_height > 80 else max_height)

    while (h_max - h_min) % floor_size != 0:
        h_max -= 1

    generateBuildingWalls(matrix, h_min, h_max, floor_size, x_min, x_max,
                          z_min, z_max, wall)
    generateFloorsDivision(matrix, h_min, h_max, floor_size, x_min, x_max,
                           z_min, z_max, wall)

    building.orientation = getOrientation()

    if building.orientation == "S":
        door_x = RNG.randint(x_min + 1, x_max - 1)
        door_z = z_max
        generateDoor(matrix, h_min + 1, door_x, door_z, (64, 9), (64, 3))
        building.entranceLot = (door_x, building.lotArea.z_max)
        for z in range(door_z + 1, building.lotArea.z_max + 1):
            matrix.setValue(h_min, door_x, z, (1, 6))
            matrix.setValue(h_min, door_x - 1, z, (1, 6))
            matrix.setValue(h_min, door_x + 1, z, (1, 6))

        # apartment windows
        generateBuildingWindows_AlongZ(matrix, h_min, h_max, floor_size, x_min,
                                       x_max, z_min)
        # corridor windows
        generateBuildingWindows_AlongZ(matrix, h_min, h_max, floor_size, x_min,
                                       x_max, z_max)
        generateCorridorInterior(matrix, h_min, h_max, floor_size, x_min,
                                 x_max, z_max - 6, z_max)
        generateFloorPlan(matrix, h_min, h_max, floor_size, x_min, x_max,
                          z_min, z_max, wall)

        generateStairs(matrix, h_min, h_max, floor_size, x_min, x_max, z_min,
                       z_max, wall)
        generateApartmentInterior(matrix, h_min, h_max, floor_size, x_min,
                                  x_max, z_min, z_max - 6)

    return building
def generateWell(matrix, h_min, h_max, x_min, x_max, z_min, z_max, biome):
    well = utilityFunctions.dotdict()
    well.type = "well"
    well.lotArea = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })

    utilityFunctions.cleanProperty(matrix, h_min + 1, h_max, x_min, x_max,
                                   z_min, z_max)

    (h_min, h_max, x_min, x_max, z_min,
     z_max) = getWellAreaInsideLot(h_min, h_max, x_min, x_max, z_min, z_max)

    well.buildArea = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })
    well.orientation = getOrientation()

    logging.info("Generating well at area {}".format(well.lotArea))
    logging.info("Construction area {}".format(well.buildArea))

    picked_wood = 'oak'
    fence = BlocksInfo.IRON_BAR_ID
    slab = BlocksInfo.getSlabId(biome, picked_wood, "Lower")
    wall = BlocksInfo.getWellWallId(biome)
    structure_bloc = BlocksInfo.getStructureBlockId(biome, picked_wood)
    pillar = BlocksInfo.getHousePillarId(biome, picked_wood)
    stairs = BlocksInfo.getStairsId(biome, picked_wood)[0]
    pavement_block = BlocksInfo.getPavmentId(biome)

    setGround(matrix, h_min - 1, x_min, x_max, z_min, z_max, structure_bloc)
    generateWall(matrix, h_min, x_min, x_max, z_min, z_max, wall, fence)
    generateCenterPart(matrix, h_min, x_min + 3, x_max - 3, z_min + 3,
                       z_max - 3, slab, structure_bloc, pillar, fence, stairs,
                       wall)

    if well.orientation == "N":
        generateEntrance(matrix, h_min, x_min + WELL_ENTRANCE_SIZE,
                         x_max - WELL_ENTRANCE_SIZE, z_min, z_min, wall)
        generateBucket(matrix, h_min + 4, x_min + (WELL_AREA_SIZE / 2),
                       z_min + (WELL_AREA_SIZE / 2), 1)
        well.entranceLot = (well.lotArea.y_min + 1,
                            well.buildArea.x_min + (WELL_AREA_SIZE / 2),
                            well.lotArea.z_min)
        door_x = x_min + WELL_ENTRANCE_SIZE
        # entrance path
        for z in range(well.lotArea.z_min, well.buildArea.z_min):
            for i in range(1, WELL_ENTRANCE_SIZE - 1):
                matrix.setValue(well.lotArea.y_min, door_x + i, z,
                                pavement_block)

    elif well.orientation == "S":
        generateEntrance(matrix, h_min, x_min + WELL_ENTRANCE_SIZE,
                         x_max - WELL_ENTRANCE_SIZE, z_max, z_max, wall)
        generateBucket(matrix, h_min + 4, x_max - (WELL_AREA_SIZE / 2),
                       z_max - (WELL_AREA_SIZE / 2), 1)
        well.entranceLot = (well.lotArea.y_min + 1,
                            well.buildArea.x_min + (WELL_AREA_SIZE / 2),
                            well.lotArea.z_max)
        door_x = x_min + WELL_ENTRANCE_SIZE
        # entrance path
        for z in range(well.buildArea.z_max + 1, well.lotArea.z_max):
            for i in range(1, WELL_ENTRANCE_SIZE - 1):
                matrix.setValue(well.lotArea.y_min, door_x + i, z,
                                pavement_block)

    elif well.orientation == "E":
        generateEntrance(matrix, h_min, x_max, x_max,
                         z_min + WELL_ENTRANCE_SIZE,
                         z_max - WELL_ENTRANCE_SIZE, wall)
        generateBucket(matrix, h_min + 4, x_max - (WELL_AREA_SIZE / 2),
                       z_min + (WELL_AREA_SIZE / 2), 1)
        well.entranceLot = (well.lotArea.y_min + 1, well.lotArea.x_max,
                            well.buildArea.z_min + (WELL_AREA_SIZE / 2))
        door_z = z_min + WELL_ENTRANCE_SIZE
        # entrance path
        for x in range(well.buildArea.x_max + 1, well.lotArea.x_max):
            for i in range(1, WELL_ENTRANCE_SIZE - 1):
                matrix.setValue(well.lotArea.y_min, x, door_z + i,
                                pavement_block)

    else:
        generateEntrance(matrix, h_min, x_min, x_min,
                         z_min + WELL_ENTRANCE_SIZE,
                         z_max - WELL_ENTRANCE_SIZE, wall)
        generateBucket(matrix, h_min + 4, x_min + (WELL_AREA_SIZE / 2),
                       z_max - (WELL_AREA_SIZE / 2), 1)
        well.entranceLot = (well.lotArea.y_min + 1, well.lotArea.x_min,
                            well.buildArea.z_min + (WELL_AREA_SIZE / 2))
        door_z = z_min + WELL_ENTRANCE_SIZE
        # entrance path
        for x in range(well.lotArea.x_min, well.buildArea.x_min):
            for i in range(1, WELL_ENTRANCE_SIZE - 1):
                matrix.setValue(well.lotArea.y_min, x, door_z + i,
                                pavement_block)

    return well
Example #9
0
def perform(level, box, options):

    logging.info("BoundingBox coordinates: ({},{}),({},{}),({},{})".format(
        box.miny, box.maxy, box.minx, box.maxx, box.minz, box.maxz))

    # ==== PREPARATION =====
    (width, height, depth) = utilityFunctions.getBoxSize(box)
    logging.info("Selection box dimensions {}, {}, {}".format(
        width, height, depth))
    world = utilityFunctions.generateMatrix(level, box, width, depth, height)
    world_space = utilityFunctions.dotdict({
        "y_min": 0,
        "y_max": height - 1,
        "x_min": 0,
        "x_max": width - 1,
        "z_min": 0,
        "z_max": depth - 1
    })
    height_map = utilityFunctions.getHeightMap(level, box, None, False)

    # === Wood quantity and Biome analyzer === #
    air_like = [
        0, 4, 5, 6, 20, 23, 29, 30, 35, 37, 38, 39, 40, 44, 46, 47, 50, 59, 66,
        83, 85, 86, 95, 102, 104, 105, 107, 126, 141, 142, 160, 175
    ]
    wood_height_map = utilityFunctions.getHeightMap(level, box, air_like, True)
    (usable_wood, biome) = EnvironmentAnalyzer.determinate_usable_wood(
        level, wood_height_map, box.minx, box.maxx, box.minz, box.maxz)

    # ===  City stats === #
    biome_with_well = ['Desert', 'Badlands']
    APARTMENT_SIZE = 2
    HOUSE_SIZE = 4
    GREENHOUSE_CAPACITY = 15
    inhabitants = 0
    greenhouse_count = 0
    well_count = 0

    # ==== PARTITIONING OF THE SELECTION IN AREA IN ORDER TO FLATTEN ====
    # Work in progress do not use
    #earthwork_height_map = utilityFunctions.getHeightMap(level,box, None, True)
    #area_partitioning_and_flattening(world_space, earthwork_height_map, world, biome)

    # ==== PARTITIONING OF NEIGHBOURHOODS ====
    (center,
     neighbourhoods) = generateCenterAndNeighbourhood(world_space, height_map)
    all_buildings = []

    # ====  GENERATING CITY CENTER ====
    minimum_h = 50
    minimum_w = 25
    mininum_d = 25

    iterate = 100
    minimum_lots = 6
    available_lots = 0
    maximum_tries = 50
    current_try = 0
    threshold = 1
    partitioning_list = []
    temp_partitioning_list = []

    # run the partitioning algorithm for iterate times to get different partitionings of the same area
    logging.info(
        "Generating {} different partitionings for the the City Centre {}".
        format(iterate, center))
    while available_lots < minimum_lots and current_try < maximum_tries:

        for i in range(iterate):

            # generate a partitioning through some algorithm
            if RNG.random() < 0.5:
                partitioning = binarySpacePartitioning(center[0], center[1],
                                                       center[2], center[3],
                                                       center[4], center[5],
                                                       [])
            else:
                partitioning = quadtreeSpacePartitioning(
                    center[0], center[1], center[2], center[3], center[4],
                    center[5], [])

            # remove invalid partitions from the partitioning
            valid_partitioning = []
            for p in partitioning:
                (y_min, y_max, x_min, x_max, z_min, z_max) = (p[0], p[1], p[2],
                                                              p[3], p[4], p[5])
                failed_conditions = []
                cond1 = utilityFunctions.hasValidGroundBlocks(
                    x_min, x_max, z_min, z_max, height_map)
                if cond1 == False: failed_conditions.append(1)
                cond2 = utilityFunctions.hasMinimumSize(
                    y_min, y_max, x_min, x_max, z_min, z_max, minimum_h,
                    minimum_w, mininum_d)
                if cond2 == False: failed_conditions.append(2)
                cond3 = utilityFunctions.hasAcceptableSteepness(
                    x_min, x_max, z_min, z_max, height_map,
                    utilityFunctions.getScoreArea_type1, threshold)
                if cond3 == False: failed_conditions.append(3)
                if cond1 and cond2 and cond3:
                    score = utilityFunctions.getScoreArea_type1(
                        height_map, x_min, x_max, z_min, z_max)
                    valid_partitioning.append((score, p))
                else:
                    logging.info(
                        "Failed Conditions {}".format(failed_conditions))

            partitioning_list.extend(valid_partitioning)
            logging.info(
                "Generated a partition with {} valid lots and {} invalids ones"
                .format(len(valid_partitioning),
                        len(partitioning) - len(valid_partitioning)))

        # order partitions by steepness
        partitioning_list = sorted(partitioning_list)
        final_partitioning = utilityFunctions.getNonIntersectingPartitions(
            partitioning_list)

        available_lots = len(final_partitioning)
        logging.info(
            "Current partitioning with most available_lots: {}, current threshold {}"
            .format(available_lots, threshold))

        threshold += 1
        current_try += 1

    logging.info("Final lots ({}) for the City Centre {}: ".format(
        len(final_partitioning), center))
    for p in final_partitioning:
        logging.info("\t{}".format(p))

    for partition in final_partitioning:
        building, apartments_inhabitants = generateBuilding(
            world, partition, height_map, usable_wood, biome)
        inhabitants += apartments_inhabitants
        all_buildings.append(building)

    # ==== GENERATING NEIGHBOURHOODS ====

    minimum_h = 10
    minimum_w = 16
    mininum_d = 16

    iterate = 100
    maximum_tries = 50
    current_try = 0
    minimum_lots = 20
    available_lots = 0
    threshold = 1
    partitioning_list = []
    final_partitioning = []

    while available_lots < minimum_lots and current_try < maximum_tries:
        partitioning_list = []
        for i in range(iterate):
            for neigh in neighbourhoods:
                logging.info(
                    "Generating {} different partitionings for the neighbourhood {}"
                    .format(iterate, neigh))

                if RNG.random() < 0.5:
                    partitioning = binarySpacePartitioning(
                        neigh[0], neigh[1], neigh[2], neigh[3], neigh[4],
                        neigh[5], [])
                else:
                    partitioning = quadtreeSpacePartitioning(
                        neigh[0], neigh[1], neigh[2], neigh[3], neigh[4],
                        neigh[5], [])

                valid_partitioning = []
                for p in partitioning:
                    (y_min, y_max, x_min, x_max, z_min,
                     z_max) = (p[0], p[1], p[2], p[3], p[4], p[5])
                    failed_conditions = []
                    cond1 = utilityFunctions.hasValidGroundBlocks(
                        x_min, x_max, z_min, z_max, height_map)
                    if cond1 == False: failed_conditions.append(1)
                    cond2 = utilityFunctions.hasMinimumSize(
                        y_min, y_max, x_min, x_max, z_min, z_max, minimum_h,
                        minimum_w, mininum_d)
                    if cond2 == False: failed_conditions.append(2)
                    cond3 = utilityFunctions.hasAcceptableSteepness(
                        x_min, x_max, z_min, z_max, height_map,
                        utilityFunctions.getScoreArea_type1, threshold)
                    if cond3 == False: failed_conditions.append(3)
                    if cond1 and cond2 and cond3:
                        score = utilityFunctions.getScoreArea_type1(
                            height_map, x_min, x_max, z_min, z_max)
                        valid_partitioning.append((score, p))
                        logging.info("Passed the 3 conditions!")
                    else:
                        logging.info(
                            "Failed Conditions {}".format(failed_conditions))

                partitioning_list.extend(valid_partitioning)
                logging.info(
                    "Generated a partition with {} valid lots and {} invalids ones"
                    .format(len(valid_partitioning),
                            len(partitioning) - len(valid_partitioning)))

        temp_partitioning_list.extend(partitioning_list)
        # order partitions by steepness
        temp_partitioning_list = sorted(temp_partitioning_list)
        final_partitioning = utilityFunctions.getNonIntersectingPartitions(
            temp_partitioning_list)

        available_lots = len(final_partitioning)
        logging.info(
            "Current neighbourhood partitioning with most available_lots: {}, current threshold {}"
            .format(available_lots, threshold))

        threshold += 1
        current_try += 1

        logging.info("Final lots ({})for the neighbourhood {}: ".format(
            len(final_partitioning), neigh))
        for p in final_partitioning:
            logging.info("\t{}".format(p))

    for partition in final_partitioning:
        if well_count < 1 and biome in biome_with_well:
            well = generateWell(world, partition, height_map, biome)
            well_count += 1
            all_buildings.append(well)
        elif greenhouse_count * GREENHOUSE_CAPACITY < inhabitants:
            greenhouse = generateGreenhouse(world, partition, height_map,
                                            usable_wood, biome)
            greenhouse_count += 1
            all_buildings.append(greenhouse)
        else:
            house = generateHouse(world, partition, height_map, usable_wood,
                                  biome)
            inhabitants += RNG.randint(1, HOUSE_SIZE)
            all_buildings.append(house)

    # ==== GENERATE PATH MAP  ====
    # generate a path map that gives the cost of moving to each neighbouring cell
    pathMap = utilityFunctions.getPathMap(height_map, width, depth)

    # ==== CONNECTING BUILDINGS WITH ROADS  ====
    logging.info("Calling MST on {} buildings".format(len(all_buildings)))
    MST = utilityFunctions.getMST_Manhattan(all_buildings, pathMap, height_map)

    pavementBlockID = BlocksInfo.getPavmentId(biome)
    for m in MST:
        p1 = m[1]
        p2 = m[2]
        logging.info("Pavement with distance {} between {} and {}".format(
            m[0], p1.entranceLot, p2.entranceLot))

        path = utilityFunctions.aStar(p1.entranceLot, p2.entranceLot, pathMap,
                                      height_map)
        if path != None:
            logging.info(
                "Found path between {} and {}. Generating road...".format(
                    p1.entranceLot, p2.entranceLot))
            GeneratePath.generatPath(world, path, height_map, pavementBlockID)
        else:
            logging.info(
                "Couldnt find path between {} and {}. Generating a straight road between them..."
                .format(p1.entranceLot, p2.entranceLot))
            GeneratePath.generatPath_StraightLine(world, p1.entranceLot[1],
                                                  p1.entranceLot[2],
                                                  p2.entranceLot[1],
                                                  p2.entranceLot[2],
                                                  height_map, pavementBlockID)

    # ==== UPDATE WORLD ====
    world.updateWorld()
def generateGreenhouse(matrix, h_min, h_max, x_min, x_max, z_min, z_max,
                       usable_wood, biome):
    greenhouse = utilityFunctions.dotdict()
    greenhouse.type = "greenhouse"
    greenhouse.lotArea = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })

    (h_min, h_max, x_min, x_max, z_min,
     z_max) = getGreenHouseAreaInsideLot(h_min, h_max, x_min, x_max, z_min,
                                         z_max)

    greenhouse.buildArea = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })
    greenhouse.orientation = getOrientation()
    door_z = greenhouse.buildArea.z_min
    door_x = greenhouse.buildArea.x_min + GREENHOUSE_WIDTH / 2
    greenhouse.entranceLot = (greenhouse.lotArea.y_min + 1, door_x,
                              greenhouse.lotArea.z_min)

    logging.info("Generating greenhouse at area {}".format(greenhouse.lotArea))
    logging.info("Construction area {}".format(greenhouse.buildArea))
    utilityFunctions.cleanProperty2(matrix, greenhouse.lotArea.y_min + 1,
                                    greenhouse.lotArea.y_max, x_min - 1,
                                    x_max + 1, z_min - 1, z_max + 1)
    utilityFunctions.cleanProperty2(matrix, h_min + 1, h_max, door_x - 1,
                                    door_x + 1, greenhouse.lotArea.z_min + 1,
                                    z_min - 1)

    picked_wood = utilityFunctions.selectRandomWood(usable_wood)
    foundation = BlocksInfo.getGreenhouseFundationId(biome, picked_wood)
    ground = BlocksInfo.getGreenhouseGroundId(biome)
    used_glass = BlocksInfo.getGreenhouseGlassId(biome)
    pavement_block = BlocksInfo.getPavmentId(biome)

    generateGroundAndCropse(matrix, greenhouse.buildArea.y_min,
                            greenhouse.buildArea.x_min,
                            greenhouse.buildArea.x_max,
                            greenhouse.buildArea.z_min,
                            greenhouse.buildArea.z_max, foundation, ground)
    generateGlassDome(matrix, greenhouse.buildArea.y_min + 1,
                      greenhouse.buildArea.y_min + GREENHOUSE_HEIGHT,
                      greenhouse.buildArea.x_min, greenhouse.buildArea.x_max,
                      greenhouse.buildArea.z_min, greenhouse.buildArea.z_max,
                      used_glass)
    generateFront(matrix, greenhouse.buildArea.y_min + 1,
                  greenhouse.buildArea.y_min + GREENHOUSE_HEIGHT,
                  greenhouse.buildArea.x_min, greenhouse.buildArea.x_max,
                  greenhouse.buildArea.z_min, greenhouse.buildArea.z_max,
                  used_glass)

    # entrance path
    for z in range(greenhouse.lotArea.z_min, door_z):
        matrix.setValue(h_min, door_x, z, pavement_block)
        matrix.setValue(h_min, door_x - 1, z, pavement_block)

    return greenhouse
Example #11
0
def generateFarm(matrix, h_min, h_max, x_min, x_max, z_min, z_max, farmType):

    farm = utilityFunctions.dotdict()
    farm.type = "farm"
    farm.lotArea = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })

    utilityFunctions.cleanProperty(matrix, h_min + 1, h_max, x_min, x_max,
                                   z_min, z_max)

    (h_min, h_max, x_min, x_max, z_min,
     z_max) = getFarmAreaInsideLot(h_min, h_max, x_min, x_max, z_min, z_max,
                                   farmType)
    farm.buildArea = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })

    logging.info("Generating farm at area {}".format(farm.lotArea))
    logging.info("Construction area {}".format(farm.buildArea))

    farm.orientation = getOrientation(matrix, farm.lotArea)

    if farmType == None:
        generateBasicPattern(matrix, h_min, x_min, x_max, z_min, z_max)
    elif farmType == "smiley":
        generateSmileyPattern(matrix, h_min, x_min, x_max, z_min, z_max)

    #create door and entrance path
    if farm.orientation == "S":
        door_x = x_max - 2
        door_z = z_max - 1
        farm.entranceLot = (door_x, farm.lotArea.z_max)
        generateEntrance(matrix, 0, h_min, door_x, door_z, door_z + 1,
                         farm.lotArea.z_max + 1)

    elif farm.orientation == "N":
        door_x = x_min + 2
        door_z = z_min + 1
        farm.entranceLot = (door_x, farm.lotArea.z_min)
        generateEntrance(matrix, 2, h_min, door_x, door_z, farm.lotArea.z_min,
                         door_z)

    elif farm.orientation == "W":
        door_x = x_min + 1
        door_z = z_max - 2
        farm.entranceLot = (farm.lotArea.x_min, door_z)
        generateEntrance(matrix, 1, h_min, door_x, door_z, farm.lotArea.x_min,
                         door_x)

    elif farm.orientation == "E":
        door_x = x_max - 1
        door_z = z_min + 2
        farm.entranceLot = (farm.lotArea.x_max, door_z)
        generateEntrance(matrix, 3, h_min, door_x, door_z, door_x + 1,
                         farm.lotArea.x_max + 1)

    return farm
def generateCrous(matrix,
                  h_min,
                  h_max,
                  x_min,
                  x_max,
                  z_min,
                  z_max,
                  ceiling=None):

    house = utilityFunctions.dotdict()
    house.type = "house"
    house.lotArea = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })

    utilityFunctions.cleanProperty(matrix, h_min + 1, h_max, x_min, x_max,
                                   z_min, z_max)

    room_size = 4
    (h_min, h_max, x_min, x_max, z_min,
     z_max) = getBuildArea(h_min, h_max, x_min, x_max, z_min, z_max, room_size)

    house.buildArea = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })

    # does not create the house if not enough space is given
    if abs(x_max - x_min) < room_size or abs(z_max - z_min) < room_size or abs(
            h_max - h_min) < 3:
        return

    logging.info("Generating lego house at area {}".format(house.lotArea))
    logging.info("Construction area {}".format(house.buildArea))

    height = 3
    floors_rooms = [0] * ((h_max - h_min) // height)
    ori = orientation()
    single_ori = RNG.random() < 0.5
    rooms = list()

    for z in range(z_min, z_max, room_size):
        for x in range(x_min, x_max, room_size):
            for f in range(h_min, h_max, height):
                ori = ori if single_ori else orientation()
                while not checkOrientation(f, x, z, matrix, ori):
                    ori = orientation()
                wood = (5, RNG.randint(0, 5))
                generateRoom(f, f + height, x, x + room_size, z, z + room_size,
                             matrix, wood,
                             (floors_rooms[(f - h_min) // height] == 0), ori)
                rooms.append([f, x, z, ori])
                floors_rooms[(f - h_min) // height] += 1
                if RNG.random() < 0.3:
                    generateRoof(f + height, x, x + room_size, z,
                                 z + room_size, matrix, wood)
                    break

    for room in rooms:
        generateDoorPath(room[0], room[1], room[2], matrix, room[3], h_min)

    for room in rooms:
        generateLadder(room[0], room[1], room[2], matrix, room[3], h_min)

    ori = orientationFromDoors(h_min, x_min, x_max, z_min, z_max, matrix, ori)
    house.orientation = ori
    generateEntrance(h_min, x_min, x_max, z_min, z_max, matrix, house, ori)

    return house
Example #13
0
def generateBuilding(matrix, h_min, h_max, x_min, x_max, z_min, z_max,
                     usable_wood, biome):

    building = utilityFunctions.dotdict()
    building.type = "building"

    building.area = utilityFunctions.dotdict({
        "y_min": h_min,
        "y_max": h_max,
        "x_min": x_min,
        "x_max": x_max,
        "z_min": z_min,
        "z_max": z_max
    })

    (h_min, h_max, x_min, x_max, z_min,
     z_max) = getBuildingAreaInsideLot(h_min, h_max, x_min, x_max, z_min,
                                       z_max)
    building.constructionArea = (h_min, h_max, x_min, x_max, z_min, z_max)

    logging.info("Generating building at area {}".format(building.area))
    logging.info("Construction area {}".format(building.constructionArea))
    utilityFunctions.cleanProperty2(
        matrix, building.area.y_min + 1, building.area.y_max, x_min - 1,
        x_max + 1,
        z_min - 3 if z_min - 3 > building.area.z_min else building.area.z_min,
        z_max + 1)

    picked_wood = utilityFunctions.selectRandomWood(usable_wood)
    wall = (159, random.randint(0, 15))
    ceiling = wall
    floor = wall
    pavement_block = BlocksInfo.getPavmentId(biome)
    slab = BlocksInfo.getSlabId(biome, picked_wood, "Upper")
    stairs = BlocksInfo.getStairsId(biome, picked_wood)
    fence = BlocksInfo.getFenceId(biome, picked_wood)
    structureBloc = BlocksInfo.getStructureBlockId(biome, picked_wood)

    floor_size = 8
    max_height = h_max - h_min
    if max_height > 32:
        h_max = h_min + random.randint(32,
                                       80 if max_height > 80 else max_height)

    while (h_max - h_min) % floor_size != 0:
        h_max -= 1

    building.orientation = getOrientation()

    if building.orientation == "S":
        door_x = RNG.randint(x_min + 1, x_max - 1)
        door_z = z_max
        utilityFunctions.cleanProperty2(matrix, h_min + 1, h_max, door_x - 1,
                                        door_x + 1, z_max + 1,
                                        building.area.z_max - 1)
        generateBuildingWalls(matrix, h_min, h_max, floor_size, x_min, x_max,
                              z_min, z_max, wall)
        generateFloorsDivision(matrix, h_min, h_max, floor_size, x_min, x_max,
                               z_min, z_max, wall)
        generateDoor(matrix, h_min + 1, door_x, door_z, (64, 9), (64, 3))
        building.entranceLot = (h_min + 1, door_x, building.area.z_max)
        for z in range(door_z + 1, building.area.z_max):
            matrix.setValue(h_min, door_x, z, pavement_block)
            matrix.setValue(h_min, door_x - 1, z, pavement_block)
            matrix.setValue(h_min, door_x + 1, z, pavement_block)
        # determine which floor have two apartment instead of one
        double_apartment_floor = pickDoubleapartmentFloor(
            h_min, h_max, floor_size)
        # apartment windows
        generateBuildingWindows_AlongZ(matrix, h_min, h_max, floor_size, x_min,
                                       x_max, z_min, double_apartment_floor)
        # corridor windows
        generateBuildingWindows_AlongZ(matrix, h_min, h_max, floor_size, x_min,
                                       x_max, z_max, [])
        generateCorridorInterior(matrix, h_min, h_max, floor_size, x_min,
                                 x_max, z_max - 6, z_max, fence)
        generateFloorPlan(matrix, h_min, h_max, floor_size, x_min, x_max,
                          z_min, z_max, wall, double_apartment_floor)

        generateStairs(matrix, h_min, h_max, floor_size, x_min, x_max, z_min,
                       z_max, wall)
        generateRoof(matrix, h_min, h_max, floor_size, x_min, x_max, z_min,
                     z_max, biome, usable_wood, wall, stairs)
        generateApartmentInterior(matrix, h_min, h_max, floor_size, x_min,
                                  x_max, z_min, z_max - 6,
                                  double_apartment_floor, usable_wood, biome,
                                  fence)
        generateBalconySouth(matrix, h_min, h_max, floor_size, x_min, x_max,
                             z_min, building.area.z_min, building.orientation,
                             double_apartment_floor, wall, slab, stairs, fence,
                             structureBloc)

        inhabitants = RNG.randint(
            1, 2) * (h_max / floor_size) + len(double_apartment_floor)
    return (building, inhabitants)