def world_perlin_noise(w, h, scale=10.0, octaves=6, persistence=0.5, lacunarity=2.0): M = Map(w, h) min_value = None max_value = None startx = random.randint(0, w * 100) starty = random.randint(0, h * 100) for y, line in enumerate(M.cells): for x, cell in enumerate(line): n = noise.pnoise2((startx + x) / scale, (starty + y) / scale, octaves=octaves, persistence=persistence, lacunarity=lacunarity, repeatx=w, repeaty=h, base=2) M[x, y].noise = n if min_value is None: min_value = n if max_value is None: max_value = n if n < min_value: min_value = n if n > max_value: max_value = n delta = (max_value - min_value) / 12 for y, line in enumerate(M.cells): for x, cell in enumerate(line): if M[x, y].noise < min_value + delta: M[x, y] = C.overworld_ocean() elif M[x, y].noise < min_value + 5 * delta: M[x, y] = C.overworld_ocean() elif M[x, y].noise < min_value + 8 * delta: M[x, y] = C.overworld_plains() elif M[x, y].noise < min_value + 10 * delta: M[x, y] = C.overworld_forest() elif M[x, y].noise < min_value + 12 * delta: M[x, y] = C.overworld_mountain() else: M[x, y] = C.overworld_pinnacle() return M
def world_test(w, h): heightmap = [] for y in range(h): line = [] for x in range(w): distance_corners = min([ sqrt(x**2 + y**2), sqrt((w-x)**2 + y**2), sqrt(x**2 + (h-y)**2), sqrt((w-x)**2 + (h-y)**2) ]) distance_edges = min([x*0.7, y*0.7, (w-x)*0.7, (h-y)*0.7]) minus = (w + h) / 3 c = random.randint(-w*0.7, -w*0.6) + distance_corners + distance_edges #print('{:> .1f}'.format(c), '', end='') line.append(c) heightmap.append(line) heightmap = diamond_square_2x(heightmap) heightmap = diamond_square_2x(heightmap, smooth_iteration=2) heightmap = diamond_square_2x(heightmap, smooth_iteration=3) heightmap = diamond_square_2x(heightmap, smooth_iteration=4) M = Map(len(heightmap[0]), len(heightmap), fill_cell=C.overworld_ocean) for y, line in enumerate(M.cells): for x, cell in enumerate(line): M[x, y] = C.overworld_ocean() if heightmap[y][x] < 0 else C.overworld_forest() M = _smooth_map(M) M = _smooth_map(M) return M
def world_test2(w=400, h=200): M = Map(w, h, fill_cell=C.overworld_ocean) ''' plates = {i: (random.randint(0, w-1), random.randint(0, h-1)) for i in range(30)} for y, line in enumerate(M.cells): for x, cell in enumerate(line): intervals = {i: (plates[i][0] - x) ** 2 + (plates[i][1] - y) ** 2 for i in plates} #print(intervals) M[x, y].plate = min(intervals.items(), key=lambda item: item[1])[0] for y, line in enumerate(M.cells): for x, cell in enumerate(line): M[x, y] = P[M[x, y].plate]() for i in plates: M[plates[i]] = C.void() ''' for y, line in enumerate(M.cells): for x, cell in enumerate(line): distance_corners = min([ sqrt(x**2 + y**2), sqrt((w-x)**2 + y**2), sqrt(x**2 + (h-y)**2), sqrt((w-x)**2 + (h-y)**2) ]) distance_edges = min([x, y, (w-x), (h-y)]) minus = (w + h) / 3 c = random.randint(-w*0.8, -w*0.6) + distance_corners + distance_edges #print('{:> .1f}'.format(c), '', end='') M[x, y] = C.overworld_ocean() if c < 0 else C.overworld_forest() #print() #for y in [0, h-1]: # for x in range(M.w): # M[x, y] = C.overworld_ocean() #for x in [0, w-1]: # for y in range(M.h): # M[x, y] = C.overworld_ocean() #for x in range(w//2-2, w//2+3): # for y in range(h//2-2, h//2+3): # M[x, y] = C.overworld_forest() #for y, line in enumerate(M.cells): # for x, cell in enumerate(line): # if sum(c.cname == 'overworld_forest' for c in M.surrounding(x, y)) >= 7: # M[x, y] = C.overworld_forest() #M = _smooth_map(M) return M
def _smooth_map(M): """ Smooth a map using cellular automata. If number of walls around the cell (including it) is more than number of floors, replace the cell with a wall. In other case replace the cell with a floor. """ # Already replaced cells must not affect current so we need a copy of the original map M2 = deepcopy(M) for y, line in enumerate(M2.cells[1: -1]): for x, _ in enumerate(line[1: -1]): true_x = x + 1 true_y = y + 1 # Check the number of walls in ORIGINAL map number_of_walls = sum( cell.cname == 'overworld_forest' for cell in [ M.cells[true_y][true_x], M.cells[true_y+1][true_x], M.cells[true_y-1][true_x], M.cells[true_y][true_x+1], M.cells[true_y+1][true_x+1], M.cells[true_y-1][true_x+1], M.cells[true_y][true_x-1], M.cells[true_y+1][true_x-1], M.cells[true_y-1][true_x-1], ] ) # And set them in smoothed map M2.cells[true_y][true_x] = ( C.overworld_forest() if number_of_walls >= 5 else C.overworld_ocean() ) return M2