def make_rivers(world): """ Make rivers """ # a 2D array of values at each pixel representing the amount of water that has flowed through # this pixel into a neighbor rainflow = np.zeros(world["heightmap"].shape, dtype=int) # a working array that represents the rain flow after a certain number of calls to flow() waterlevel = np.zeros(world["heightmap"].shape, dtype=int) # an array of (x, y) coordinates of the nearest lowest neighbor lowest_neighbors = np.empty(world["heightmap"].shape, dtype="int, int") x_, y_ = rainflow.shape for x in xrange(x_): for y in xrange(y_): altitude = world["heightmap"][x, y] if altitude > world["sea_level"]: rainflow[x, y] = 1 waterlevel[x, y] = 1 their_altitude, t_x, t_y = find_neighbors(world["heightmap"], (x, y), sort=True)[0] if their_altitude < world["heightmap"][x, y]: lowest_neighbors[x, y] = (t_x, t_y) print(lowest_neighbors[10, 10]) def flow(): x_, y_ = rainflow.shape for x in xrange(x_): for y in xrange(y_): if waterlevel[x, y] != 0: # land pixels # get the lowest neighbor n = lowest_neighbors[x, y] # is the lowest neighbor less than me? if n: # move my water to the neighbor waterlevel[n[0], n[1]] += waterlevel[x, y] # rainflow[n[0], n[1]] += waterlevel[x, y] waterlevel[x, y] = 0 for i in xrange(3): print("Flow %i" % i) flow() return waterlevel
def next(self, last_elevation=None): if last_elevation is None: last_elevation = self.elevation elevation, x, y = find_neighbors(self.river.world['heightmap'], self.location, sort=True)[0] print self.elevation, elevation, x, y if self.river.world['river_array'][x][y]: # neighbor is a river segment print('encountered river at ', x, y) return False # if elevation == self.elevation: # print("Making a lake at %i, %i" % (x, y)) # lake = Lake(self.river, (x, y), self.elevation) # self.next_segments.append(lake) # lake.fill() if elevation <= last_elevation and elevation > self.river.world['sea_level']: segment = RiverSegment(self.river, (x, y)) self.next_segments.append(segment) segment.next(elevation) else: print('Reached sea level')
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