This is the code that generate this kind of terrain (background for my "platform" game): https://drive.google.com/open?id=0B5yRPbmIAqr0X2wwX1BwNTZZMHc
(I hate python so sorry if this is an horrible code, and english is not my main language, so be patient pls)
import sys
import random
import pprint
import math
w = 350 #width of the terrain
h = 350 #height " " "
sz = 10 #size of a tile
sz_x = w / sz
sz_y = h / sz
area = sz_x*sz_y
bkg = [[' ' for x in range(sz_x)] for y in range(sz_y)] #initialinzing background matrix
plates = [' ', '/', '.', 'I', '#'] #tile types
#each plates has it own probability to be "spawned", the following array is
#defined as couples of (total_previous_probability + this_probability / 2, (this_probability / 2) ^2)
probability = [[2.5, 2.5**2], [35, 30**2], [72.5, 7.5**2], [85, 5**2], [95, 5**2]] #5, 60, 15, 10, 10
temp_probability = [0, 0, 0, 0, 0]
nm_plates = [0,0,0,0,0] #for debug purpose
def get_random_plate(temp_prob):
plate = 0
max_prob = 0
i = random.randint(0, 100)
for p in range(len(plates)):
prob = -(i - probability[p][0])**2 + probability[p][1] + math.sqrt(temp_prob[p] / 9);
if(prob > 0 and prob + temp_prob[p] > max_prob):
max_prob = prob+ temp_prob[p]
plate = p
return plate
#list of predefined point (x, y, types), you can make this random
#in the link you can see five different "big areas" of one types built around theese point
#you can have a lot more of this points, more points of the same time you
#have in a little area more this area will be filled with the type of that points
sp_point = [
[10, 10, 0],
[27, 5, 0],
[15, 25, 2],
[25, 25, 2],
[5, 29, 3],
[16, 16, 4],
]
def create_bkg(temp_prob):
for y in range(sz_y):
for x in range(sz_x):
temp_prob = [0, 0, 0, 0, 0]
for p in sp_point:
sqrDist = (x - p[0])**2 + (y - p[1])**2
temp_prob[p[2]] += (area / (sqrDist + 0.1))**3
plate = get_random_plate(temp_prob)
nm_plates[plate] += 1
bkg[x][y] = plates[plate]
def print_bkg():
for y in range(sz_y):
for x in range(sz_x):
sys.stdout.write(bkg[x][y])
print ''
print '\n'
create_bkg(temp_probability)
print_bkg()
pprint.pprint(nm_plates)
This generates the tile map, then I think you can create something like an height map: you read each tile of the matrix and "make it higher or lower" (I don't know how to say that) based on the surrounding tiles:
#pseudo code
if (this_tile_is_a_mountain) count mountain tiles in an area of x tile;
this_height += (number_of_mountain_tiles_found * x)^y / z
#and so on, same for lakes
In the code above you can edit some line to change the behaviour of the algorithm:
temp_prob[p[2]] += (area / (sqrDist + 0.1))**3 #you can change how temp_prob is computed
#more higher it is more "dense" will be the "one type" areas
#or you can reduce the effect it has on the result editing the following lines:
prob = -(i - probability[p][0])**2 + probability[p][1] + math.sqrt(temp_prob[p] / 9); #change this nine, remove the sqrt, add another sqrt sqrt(sqrt(x))
if(prob > 0 and prob + temp_prob[p] > max_prob): //add a here: sqrt(temp_prob[p])
max_prob = prob+ temp_prob[p] //or add it here, or both
plate = p
Just try
(I really need someone who can rewrite this in real english...)