def make_rivers(world): """ Generate rivers. Returns a tuple containing: - River instances - new world dictionary, containging: - new heightmap after river erosion and deposition - river_array: numpy boolean array in shape of heightmap showing where rivers are """ mountain_cutoff = world['max_height'] - 15 mountains = np.transpose(np.nonzero(world['heightmap'] >= mountain_cutoff)) np.random.shuffle(mountains) log('%i mountains or %0.5f%%' % (len(mountains), (float(len(mountains)) / float(world['size']**2)) * 100)) num_rivers = randint(0, int(len(mountains) * 0.10)) log('Making %i rivers' % num_rivers) river_sources = mountains[:num_rivers] # since rivers look the same on the images, this is a boolean array world['river_array'] = np.zeros(world['heightmap'].shape, dtype=np.bool) def get_elevation(loc): return world['heightmap'][loc[0], loc[1]] def is_river(loc): return world['river_array'][loc[0], loc[1]] is True def make_river_segment(loc): print(loc) world['river_array'][loc[0], loc[1]] = True rivers = [] for source in river_sources: current_location = source current_elevation = get_elevation(current_location) can_continue = True while current_elevation >= world['sea_level'] and can_continue: # get neighboring pixels neighbors = find_neighbors(world['heightmap'], current_location, sort=True)[0] # lowest neighbor is higher than me # if neighbors[0] > current_elevation): # # make a lake here # pass next_segment = neighbors[1], neighbors[2] # Is there a river here? if is_river(next_segment): print('River found at %i, %i', current_location) can_continue = False make_river_segment(current_location) current_location = next_segment current_elevation = get_elevation(current_location) # river = River(world, source) # river.flow() # world = river.world # rivers.append(river) return rivers, world
with Timer('Generating terrain'): # this function is expected to take ~30 seconds to run on the # following sizes: # 513 = 2-4 seconds # 1025 = 8-9 seconds # 2049 = 35-40 seconds heightmap = make_terrain(terrain_image, size=SIZE) img.save('images/heightmap.png') world = dict(size=SIZE, heightmap=heightmap, min_height=np.min(heightmap), max_height=np.max(heightmap), avg_height=np.average(heightmap)) log("Min height: %i\n" "Max height: %i\n" "Avg height: %i" % (world['min_height'], world['max_height'], world['avg_height'])) # decide the sea level sea_level_percent = random.randint(50, 70) world['sea_level'] = elevation_at_percent_surface(world, sea_level_percent) log('Sea level: %i%% @ %i' % (sea_level_percent, world['sea_level'])) # TERRAIN IMAGE with Timer('Making terrain image'): def delta_sea_level_func(cell): if cell < world['sea_level']: return -(100 - (cell / world['sea_level']) * 100)