(Please note, I am aware that the generation is not truly random and relies on mathematical equations, and that my language of choice is C++)
So I've been learning programming for a while now and I'm looking to make a top down 2D game. I want this game to generate random terrain pretty much like Dwarf Fortress but with sprites, however for this question let's just say that there just ASCII characters. I want it to generate mountains, rivers, inland lakes etc. I know of algorithms but have not been able to find a list of them all. The ones i know of are:
Perlin Noise, Diamond Square, Midpoint Displacement and some other minor ones.
However I don't know which one to use and struggle to find a good article on any of them. Is there one right for the job, or does it just come down to personal opinion? And if you can find a list of all the algorithms and maybe a good article on one it would really help. Thanks!
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])**2 + probability[p] + 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)**2 + (y - p)**2 temp_prob[p] += (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] += (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])**2 + probability[p] + 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
(I really need someone who can rewrite this in real english...)