fix(map-generator): improve continent generation

This commit is contained in:
Mahdi Dibaiee 2019-04-24 15:00:45 +04:30
parent 3bec4d7486
commit b377c6dd5f
3 changed files with 52 additions and 19 deletions

View File

@ -46,9 +46,9 @@ class TuneB(tune.Trainable):
return self.model.restore(path) return self.model.restore(path)
A_params = { A_params = {
'batch_size': tune.grid_search([5, 16, 32, 64]), 'batch_size': tune.grid_search([32]),
'layers': tune.grid_search([[16, 16], [32, 32], [128, 128]]), 'layers': tune.grid_search([[32, 32]]),
'lr': tune.grid_search([1e-4, 1e-3, 1e-2]), 'lr': tune.grid_search([1e-4]),
'optimizer': tune.grid_search([tf.keras.optimizers.Adam]), 'optimizer': tune.grid_search([tf.keras.optimizers.Adam]),
} }

View File

@ -102,7 +102,7 @@ def dataframe_to_dataset_temp_precip(df):
tf_output = np.concatenate((tf_output, df[output].values), axis=0) tf_output = np.concatenate((tf_output, df[output].values), axis=0)
tf_inputs = tf.cast(normalize_ndarray(tf_inputs), tf.float32) tf_inputs = tf.cast(normalize_ndarray(tf_inputs), tf.float32)
tf_output = tf.cast(tf_output, tf.float32) tf_output = tf.cast(normalize_ndarray(tf_output), tf.float32)
logger.debug('dataset size: rows=%d, input_columns=%d, num_classes=%d', int(tf_inputs.shape[0]), input_columns, num_classes) logger.debug('dataset size: rows=%d, input_columns=%d, num_classes=%d', int(tf_inputs.shape[0]), input_columns, num_classes)
return int(tf_inputs.shape[0]), input_columns, num_classes, None, tf.data.Dataset.from_tensor_slices((tf_inputs, tf_output)) return int(tf_inputs.shape[0]), input_columns, num_classes, None, tf.data.Dataset.from_tensor_slices((tf_inputs, tf_output))

View File

@ -49,11 +49,12 @@ parameters = {
'max': 0.99, 'max': 0.99,
'step': 0.01 'step': 0.01
}, },
'mountain_jaggedness': { 'mountain_concentration': {
'default': 1, 'default': 1,
'type': 'int', 'type': 'float',
'min': 0, 'min': 0,
'max': 5, 'max': 5,
'step': 0.1
}, },
'mountain_sea_distance': { 'mountain_sea_distance': {
'default': 50, 'default': 50,
@ -78,7 +79,7 @@ parameters = {
'max': 1, 'max': 1,
'step': 0.01 'step': 0.01
}, },
'mountain_area_elevation_n': { 'mountain_area_elevation_points': {
'default': 5, 'default': 5,
'type': 'int', 'type': 'int',
'min': 0, 'min': 0,
@ -94,6 +95,13 @@ parameters = {
'default': 5, 'default': 5,
'type': 'int', 'type': 'int',
}, },
'continent_spacing': {
'default': 0.3,
'type': 'float',
'min': 0,
'max': 1,
'step': 0.1
},
'seed': { 'seed': {
'default': '', 'default': '',
'type': 'int', 'type': 'int',
@ -114,6 +122,7 @@ def s(x):
def is_ground(value): def is_ground(value):
return value > p['water_level'] return value > p['water_level']
# TODO: should check as a sphere
def in_range(p, m, size): def in_range(p, m, size):
x, y = p x, y = p
mx, my = m mx, my = m
@ -130,8 +139,15 @@ def bound_check(ground, point):
x, y = point x, y = point
w, h = ground.shape w, h = ground.shape
x = max(min(x, w - 1), 0) if x < 0:
y = max(min(y, h - 1), 0) x = w + x
elif x >= w:
x = x - w
if y < 0:
y = h + y
elif y >= h:
y = y - h
return (x, y) return (x, y)
@ -145,7 +161,10 @@ def continent_agent(ground, position, size):
trials = 0 trials = 0
while True: while True:
if size <= 0 or trials > CONTINENT_MAX_TRIALS: break # if trials > CONTINENT_MAX_TRIALS:
# print('couldnt proceed')
# if size <= 0 or trials > CONTINENT_MAX_TRIALS: break
if size <= 0: break
dx = np.random.randint(2) or -1 dx = np.random.randint(2) or -1
dy = np.random.randint(2) or -1 dy = np.random.randint(2) or -1
@ -159,13 +178,14 @@ def continent_agent(ground, position, size):
else: else:
x, y = new_point x, y = new_point
x, y = bound_check(ground, (x, y))
if not is_ground(ground[x, y]) and in_range((x, y), position, size): if not is_ground(ground[x, y]) and in_range((x, y), position, size**2 * np.pi):
trials = 0 trials = 0
size -= 1 size -= 1
ground[x, y] = np.random.randint(1, p['ground_noise']) ground[x, y] = np.random.randint(1, p['ground_noise'])
else: # else:
trials += 1 # trials += 1
def neighbours(ground, position, radius): def neighbours(ground, position, radius):
x, y = position x, y = position
@ -177,13 +197,13 @@ def away_from_sea(ground, position, radius=p['mountain_sea_distance']):
return sea < p['mountain_sea_threshold'] return sea < p['mountain_sea_threshold']
def random_elevate_agent(ground, position, height, size=p['mountain_area_elevation_n']): def random_elevate_agent(ground, position, height, size=p['mountain_area_elevation_points']):
position = position + np.random.random_integers(-p['mountain_area_elevation_area'], p['mountain_area_elevation_area'], size=2) position = position + np.random.random_integers(-p['mountain_area_elevation_area'], p['mountain_area_elevation_area'], size=2)
for i in range(size): for i in range(size):
d = DIRECTIONS[np.random.randint(len(DIRECTIONS))] d = DIRECTIONS[np.random.randint(len(DIRECTIONS))]
change = height * p['mountain_area_elevation'] + np.random.randint(p['mountain_jaggedness'] + 1) change = height * p['mountain_area_elevation']
new_index = bound_check(ground, position + np.array(d)) new_index = bound_check(ground, position + np.array(d))
if is_ground(ground[new_index]): if is_ground(ground[new_index]):
@ -202,14 +222,16 @@ def mountain_agent(ground, position):
last_height = height last_height = height
for i in range(1, height): for i in range(1, height):
for d in DIRECTIONS: for d in DIRECTIONS:
change = np.random.randint(p['mountain_jaggedness'] + 1) change = np.random.randint(p['mountain_concentration'] + 1)
distance = np.array(d)*i distance = np.array(d)*i
new_index = bound_check(ground, position + distance) new_index = bound_check(ground, position + distance)
if is_ground(ground[new_index]): if is_ground(ground[new_index]):
ground[new_index] = last_height - change ground[new_index] = last_height - change
last_height = last_height - p['mountain_jaggedness'] last_height = last_height - change
if last_height < 0:
break
random_elevate_agent(ground, position, height) random_elevate_agent(ground, position, height)
@ -234,14 +256,23 @@ def generate_map(**kwargs):
ground = np.zeros((width, height)) ground = np.zeros((width, height))
ground_size = width * height * (1 - p['water_proportion']) ground_size = width * height * (1 - p['water_proportion'])
print(ground_size / ground.size)
# position = (int(width / 2), int(height / 2)) # position = (int(width / 2), int(height / 2))
# ground_size = width * height * GROUND_PROPORTION # ground_size = width * height * GROUND_PROPORTION
# continent_agent(ground, position, size=ground_size) # continent_agent(ground, position, size=ground_size)
position = (0, int(height / 2))
ym = 1
for continent in range(continents): for continent in range(continents):
position = (np.random.randint(0, width), np.random.randint(0, height)) position = (position[0] + np.random.randint(p['continent_spacing'] * width * 0.8, p['continent_spacing'] * width * 1.2),
position[1] + ym * np.random.randint(p['continent_spacing'] * height * 0.8, p['continent_spacing'] * height * 1.2))
print(position) print(position)
continent_agent(ground, position, size=ground_size)
ym = ym * -1
random_size = ground_size / continents
continent_agent(ground, position, size=random_size)
ground = ndimage.gaussian_filter(ground, sigma=(1 - p['sharpness']) * 20) ground = ndimage.gaussian_filter(ground, sigma=(1 - p['sharpness']) * 20)
@ -258,6 +289,8 @@ def generate_map(**kwargs):
print(np.min(ground), np.max(ground), p['max_elevation']) print(np.min(ground), np.max(ground), p['max_elevation'])
print(np.unique(ground)) print(np.unique(ground))
print(np.count_nonzero(ground) / ground.size)
plt.imshow(ground.T, cmap=greys, norm=norm) plt.imshow(ground.T, cmap=greys, norm=norm)
figfile = BytesIO() figfile = BytesIO()