-- height constraints
local min_height = 10
local max_height = 100
-- the grid
local K = 4
local M = 2^K -- the field is cyclic integer grid 0 <= x,y < M (x=M is the same point as x=0)
local heights = {} -- min_height <= heights[x][y] <= max_height
for x = 0, M-1 do
heights[x] = {}
end
-- set corners height (all 4 corners are the same point because of cyclic field)
heights[0][0] = (min_height + max_height) / 2
local delta_height = (max_height - min_height) * 0.264
local side = M
local sqrt2 = 2^0.5
repeat
local dbl_side = side
side = side/2
-- squares
for x = side, M, dbl_side do
for y = side, M, dbl_side do
local sum =
heights[(x-side)%M][(y-side)%M]
+ heights[(x-side)%M][(y+side)%M]
+ heights[(x+side)%M][(y-side)%M]
+ heights[(x+side)%M][(y+side)%M]
heights[x][y] = sum/4 + (2*math.random()-1) * delta_height
end
end
delta_height = delta_height / sqrt2
-- diamonds
for x = 0, M-1, side do
for y = (x+side) % dbl_side, M-1, dbl_side do
local sum =
heights[(x-side)%M][y]
+ heights[x][(y-side)%M]
+ heights[x][(y+side)%M]
+ heights[(x+side)%M][y]
heights[x][y] = sum/4 + (2*math.random()-1) * delta_height
end
end
delta_height = delta_height / sqrt2
until side == 1
-- draw field
for x = 0, M-1 do
local s = ''
for y = 0, M-1 do
s = s..' '..tostring(math.floor(heights[x][y]))
end
print(s)
end