## Randomly generating terrains

… aka “When the Creator misplaces a parenthesis”. :)

So my first attempt to write a program to generate random but pleasing landforms for my Sim on a Stick did not go quite as expected. Bit spikey, for instance.

But then I found a misplaced parenthesis! And things got better. I think I am liking the algorithm… For the curious, here is the basic (recursive, self-similar) routine, in everyone’s favorite language: Python. (Squished down to fit in the weblog here, not guaranteed to compile as-is.)

```def fill_in_terrain(t,lowx,lowy,maxx,maxy):
''' Takes the input terrain, where the low-by-max '''
''' corners are already filled in, and fills in '''
''' everything inside those corners, by the '''
''' Magic of Recursion. '''
if maxx-lowx<2: return t
if maxy-lowy<2: return t
xmid = int((lowx+maxx)/2)
ymid = int((lowy+maxy)/2)
hscale = (maxx - lowx) * HSCALE
# first the corners
if t[lowx][ymid] is None:
t[lowx][ymid] = (t[lowx][lowy] + t[lowx][maxy]) / 2
+ hscale - math.floor(2*hscale*random.random())
if t[maxx][ymid] is None:
t[maxx][ymid] = (t[maxx][lowy] + t[maxx][maxy]) / 2
+ hscale - math.floor(2*hscale*random.random())
if t[xmid][lowy] is None:
t[xmid][lowy] = (t[lowx][lowy] + t[maxx][lowy]) / 2
+ hscale - math.floor(2*hscale*random.random())
if t[xmid][maxy] is None:
t[xmid][maxy] = (t[lowx][maxy] + t[maxx][maxy]) / 2
+ hscale - math.floor(2*hscale*random.random())
# then the center
if t[xmid][ymid] is None:
t[xmid][ymid] = (t[lowx][ymid]+t[maxx][ymid]
+ t[xmid][lowy]+[xmid][maxy])/4
+ hscale - math.floor(2*hscale*random.random())
# and recurse on the four quadrants
t = fill_in_terrain(t,lowx,lowy,xmid,ymid)
t = fill_in_terrain(t,lowx,ymid,xmid,maxy)
t = fill_in_terrain(t,xmid,lowy,maxx,ymid)
t = fill_in_terrain(t,xmid,ymid,maxx,maxy)
return t

def get_terrain(x,y):
''' returns an [x][y] array of floats representing a terrain; '''
''' range unpredictable '''
''' x and y ought to be powers of two, for best results.  '''
''' oh, and equal I suppose '''
answer = [ [None for a in range(y+1)] for b in range(x+1) ]