def waitCloseDataSet(samples, robotHeight, dataset): for i in range(samples): x = 0 y = 1 z = uniform(1.5,2) #height path = [] for k in range(10): path.append([x,y,z]) trans = GeneratePath.position_transform(path,robotHeight) dataset.newSequence() for k in range(len(trans)): if k < 2: smile = 0.25 eyebrow = 0 elif k < 6: smile = 0.25 + k/10 eyebrow = -k/8 else: smile = 0.75 eyebrow = -6/8 pupils = pupilTracking(trans[k][1], trans[k][2]) dataset.appendLinked(trans[k],[smile,pupils[0], pupils[1],eyebrow]) return dataset
def leaveDataSet(samples, enviroment,robotHeight, prefSpeed, distPreferences, dataset ): xMax,xMin,yMax,yMin = enviroment careDist,goodDist = distPreferences for i in range(samples): z = uniform(1.5,2) #height endx = uniform(xMin,xMax) endy = yMax dist = uniform(goodDist,careDist) startx = uniform(-dist,dist) starty = math.sqrt(dist**2 - startx**2) path = GeneratePath.pathSpeed([startx,starty,z],[endx,endy,z],prefSpeed) trans = GeneratePath.position_transform(path,robotHeight) dataset.newSequence() for k in range(len(trans)): target = [] if k < 2: target.append(0.25) #smile else: target.append(-0.5) target.extend(pupilTracking(trans[k][1], trans[k][2])) target.append(0) #eyebrows dataset.appendLinked(trans[k],target) return dataset
def approachDataSet(samples, enviroment,robotHeight, prefSpeed, distPreferences, dataset ): xMax,xMin,yMax,yMin = enviroment careDist,goodDist = distPreferences for i in range(samples): z = uniform(1.5,2) #height startx = uniform(xMin,xMax) starty = yMax endx = 0 endy = 1 path = GeneratePath.pathSpeed([startx,starty,z],[endx,endy,z],prefSpeed) trans = GeneratePath.position_transform(path,robotHeight) dataset.newSequence() for param in trans: target = [] if param[0] < careDist: target.append(0.25) #smile else: target.append(0) target.extend(pupilTracking(param[1], param[2])) target.append(0) #eyebrows dataset.appendLinked(param,target) return dataset
def waitFarDataSet(samples,distPref,robotHeight,dataset): """ Generates a dataset with samples number of samples, where each sample is a series of identical [x,y,z] cordinates chosen randomly between the "care" and "good" distance from the robot. """ careDist,goodDist = distPref for i in range(samples): dist = uniform(goodDist,careDist) x = uniform(-dist,dist) y = math.sqrt(dist**2 - x**2) z = uniform(1.5,2) #height path = [] for k in range(10): path.append([x,y,z]) trans = GeneratePath.position_transform(path,robotHeight) dataset.newSequence() for k in range(len(trans)): if k < 2: smile = 0.25 eyebrow = 0 elif k < 6: smile = 0.25 - k/5 eyebrow = k/8 else: smile = -0.75 eyebrow = 6/8 pupils = pupilTracking(trans[k][1], trans[k][2]) dataset.appendLinked(trans[k],[smile,pupils[0], pupils[1],eyebrow]) return dataset
def testFace(enviroment,tests,speedPreferences, distancePreferences, updateTime, robotHeight, network): xMax,xMin,yMax,yMin = enviroment careDist,goodDist = distancePreferences slowSpeed, prefSpeed, fastSpeed = speedPreferences random.seed() """ Sets up the window for displaying the parametrized face """ center = graphics.Point(200,200) win = graphics.GraphWin('Face', 400, 400,autoflush=False) # give title and dimensions win.setBackground('white') win.setCoords(0, 0, 400, 400) """ Sets up the window for plotting the position of the person the face is looking at """ fig = plt.figure() ax = fig.add_subplot(1, 1, 1) createFigure(enviroment, distancePreferences,fig,ax) message = graphics.Text(graphics.Point(200, 380), 'Click to start simulation.') message.draw(win) win.getMouse() message.undraw() win.update() lingerTestPath = [] # Linger at comfortable distance for i in range(tests.get("lingerFar")): z = random.uniform(1.5,2) startx = random.uniform(xMin,xMax) starty = yMax dist = random.uniform(goodDist,careDist) endx = random.uniform(-dist,dist) endy = math.sqrt(dist**2 - endx**2) timesLingering = random.randrange(6,15) lingerTestPath.extend(GeneratePath.moveAndLinger([startx,starty,z],[endx,endy,z],prefSpeed,timesLingering)) #linger too close for i in range(tests.get("lingerClose")): z = random.uniform(1.5,2) startx = random.uniform(xMin,xMax) starty = yMax #dist = random.uniform(enviroment[3],tooClose) # endx = random.uniform(-dist,dist) #endy = math.sqrt(dist**2 - endx**2) endx = 0 endy = 1 timesLingering = random.randrange(6,15) lingerTestPath.extend(GeneratePath.moveAndLinger([startx,starty,z],[endx,endy,z],prefSpeed,timesLingering)) trans = GeneratePath.position_transform(lingerTestPath,robotHeight) print("\n---------------- Lingering tests ------------------ \n\n") iterateNetThroughPath(lingerTestPath, trans, prefSpeed, network, center, win, updateTime ) # approach, linger, leave tests plt.close() fig = plt.figure() ax = fig.add_subplot(1, 1, 1) createFigure(enviroment, distancePreferences,fig,ax) approachLingerLeavePath = [] for i in range(tests.get("approachLingerLeaveClose")): z = random.uniform(1.5,2) startx = random.uniform(xMin,xMax) starty = yMax stoppx = 0 stoppy = 1 timesLingering = random.randrange(6,15) exitx = random.uniform(xMin,xMax) exity = yMax approachLingerLeavePath.extend(GeneratePath.approachLingerLeave(prefSpeed, [startx,starty,z], [stoppx,stoppy,z], [exitx,exity,z], timesLingering)) trans = GeneratePath.position_transform(approachLingerLeavePath,robotHeight) print("\n---------------- Approach Linger Leave Close tests ------------------ \n\n") iterateNetThroughPath(approachLingerLeavePath, trans, prefSpeed, network, center, win, updateTime ) message.draw(win) win.getMouse() message.undraw() win.update() plt.close() fig = plt.figure() ax = fig.add_subplot(1, 1, 1) createFigure(enviroment, distancePreferences,fig,ax) approachLingerLeavePath = [] for i in range(tests.get("approachLingerLeaveFar")): z = random.uniform(1.5,2) startx = random.uniform(xMin,xMax) starty = yMax dist = random.uniform(goodDist,careDist) stoppx = random.uniform(-dist,dist) stoppy = math.sqrt(dist**2 - stoppx**2) timesLingering = random.randrange(6,15) exitx = random.uniform(xMin,xMax) exity = yMax approachLingerLeavePath.extend(GeneratePath.approachLingerLeave(prefSpeed,[startx,starty,z], [stoppx,stoppy,z], [exitx,exity,z], timesLingering)) trans = GeneratePath.position_transform(approachLingerLeavePath,robotHeight) print("\n---------------- Approach Linger Leave Far tests ------------------ \n\n") iterateNetThroughPath(approachLingerLeavePath, trans, prefSpeed, network, center, win, updateTime ) message.draw(win) win.getMouse() message.undraw() win.update() plt.close() fig = plt.figure() ax = fig.add_subplot(1, 1, 1) createFigure(enviroment, distancePreferences,fig,ax) #random movement tests path = GeneratePath.randomMovement(enviroment,tests.get("randomMove"),random.uniform(1.5,2),prefSpeed) trans = GeneratePath.position_transform(path,robotHeight) print("\n---------------- Random movement tests ------------------ \n\n") iterateNetThroughPath(path, trans, prefSpeed, network, center, win, updateTime ) message = graphics.Text(graphics.Point(200, 380), 'Click to close window.') message.draw(win) win.getMouse() win.close() plt.close()
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()
def testFace(enviroment, tests, speedPreferences, distancePreferences, updateTime, robotHeight, network): xMax, xMin, yMax, yMin = enviroment careDist, goodDist = distancePreferences slowSpeed, prefSpeed, fastSpeed = speedPreferences random.seed() """ Sets up the window for displaying the parametrized face """ center = graphics.Point(200, 200) win = graphics.GraphWin('Face', 400, 400, autoflush=False) # give title and dimensions win.setBackground('white') win.setCoords(0, 0, 400, 400) """ Sets up the window for plotting the position of the person the face is looking at """ fig = plt.figure() ax = fig.add_subplot(1, 1, 1) createFigure(enviroment, distancePreferences, fig, ax) message = graphics.Text(graphics.Point(200, 380), 'Click to start simulation.') message.draw(win) win.getMouse() message.undraw() win.update() lingerTestPath = [] # Linger at comfortable distance for i in range(tests.get("lingerFar")): z = random.uniform(1.5, 2) startx = random.uniform(xMin, xMax) starty = yMax dist = random.uniform(goodDist, careDist) endx = random.uniform(-dist, dist) endy = math.sqrt(dist**2 - endx**2) timesLingering = random.randrange(6, 15) lingerTestPath.extend( GeneratePath.moveAndLinger([startx, starty, z], [endx, endy, z], prefSpeed, timesLingering)) #linger too close for i in range(tests.get("lingerClose")): z = random.uniform(1.5, 2) startx = random.uniform(xMin, xMax) starty = yMax #dist = random.uniform(enviroment[3],tooClose) # endx = random.uniform(-dist,dist) #endy = math.sqrt(dist**2 - endx**2) endx = 0 endy = 1 timesLingering = random.randrange(6, 15) lingerTestPath.extend( GeneratePath.moveAndLinger([startx, starty, z], [endx, endy, z], prefSpeed, timesLingering)) trans = GeneratePath.position_transform(lingerTestPath, robotHeight) print("\n---------------- Lingering tests ------------------ \n\n") iterateNetThroughPath(lingerTestPath, trans, prefSpeed, network, center, win, updateTime) # approach, linger, leave tests plt.close() fig = plt.figure() ax = fig.add_subplot(1, 1, 1) createFigure(enviroment, distancePreferences, fig, ax) approachLingerLeavePath = [] for i in range(tests.get("approachLingerLeaveClose")): z = random.uniform(1.5, 2) startx = random.uniform(xMin, xMax) starty = yMax stoppx = 0 stoppy = 1 timesLingering = random.randrange(6, 15) exitx = random.uniform(xMin, xMax) exity = yMax approachLingerLeavePath.extend( GeneratePath.approachLingerLeave(prefSpeed, [startx, starty, z], [stoppx, stoppy, z], [exitx, exity, z], timesLingering)) trans = GeneratePath.position_transform(approachLingerLeavePath, robotHeight) print( "\n---------------- Approach Linger Leave Close tests ------------------ \n\n" ) iterateNetThroughPath(approachLingerLeavePath, trans, prefSpeed, network, center, win, updateTime) message.draw(win) win.getMouse() message.undraw() win.update() plt.close() fig = plt.figure() ax = fig.add_subplot(1, 1, 1) createFigure(enviroment, distancePreferences, fig, ax) approachLingerLeavePath = [] for i in range(tests.get("approachLingerLeaveFar")): z = random.uniform(1.5, 2) startx = random.uniform(xMin, xMax) starty = yMax dist = random.uniform(goodDist, careDist) stoppx = random.uniform(-dist, dist) stoppy = math.sqrt(dist**2 - stoppx**2) timesLingering = random.randrange(6, 15) exitx = random.uniform(xMin, xMax) exity = yMax approachLingerLeavePath.extend( GeneratePath.approachLingerLeave(prefSpeed, [startx, starty, z], [stoppx, stoppy, z], [exitx, exity, z], timesLingering)) trans = GeneratePath.position_transform(approachLingerLeavePath, robotHeight) print( "\n---------------- Approach Linger Leave Far tests ------------------ \n\n" ) iterateNetThroughPath(approachLingerLeavePath, trans, prefSpeed, network, center, win, updateTime) message.draw(win) win.getMouse() message.undraw() win.update() plt.close() fig = plt.figure() ax = fig.add_subplot(1, 1, 1) createFigure(enviroment, distancePreferences, fig, ax) #random movement tests path = GeneratePath.randomMovement(enviroment, tests.get("randomMove"), random.uniform(1.5, 2), prefSpeed) trans = GeneratePath.position_transform(path, robotHeight) print("\n---------------- Random movement tests ------------------ \n\n") iterateNetThroughPath(path, trans, prefSpeed, network, center, win, updateTime) message = graphics.Text(graphics.Point(200, 380), 'Click to close window.') message.draw(win) win.getMouse() win.close() plt.close()
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, 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()