## Java Diamond-Square Terrain

Recently I've been experimenting with 2D terrain generation, mostly side-view terraria-like terrain. I settled on the Diamond Square algorithm and I almost got the heights working but I'm pretty sure I'm applying it wrong. I'm trying to generate the values and then apply the heights to the Y of blocks. I'll post my code below and let me explain what the different values are.

Here's where I apply the values from the diamond-square:

Java Code:
```public static Chunk generateChunk()
{
Block[][] blocks = new Block[Chunk.CHUNK_WIDTH][Chunk.CHUNK_HEIGHT]; // CHUNK_WIDTH and CHUNK_HEIGHT are 9
Chunk chunk = new Chunk(blocks); // Chunk just stores an array of blocks, like the one above
double[][] noise = DiamondSquare.diamondSquare();

for (int x = 0; x < blocks.length; x++)
{
for (int y = 0; y < blocks[0].length; y++)
{
blocks[x][y] = new Block(BlockType.DIRT, x * Block.BLOCK_WIDTH, y * Block.BLOCK_HEIGHT); // BLOCK_WIDTH and BLOCK_HEIGHT are 32, BlockType just stores textures
}
}

for (int x = 0; x < noise.length; x++)
{
for (int y = 0; y < noise[0].length; y++)
{
int height = (int) (Math.abs(noise[x][y]) / Block.BLOCK_HEIGHT); // I don't want negative values and I was trying to divide the diamond-square value so each block is 32 apart

System.out.println(height);

blocks[x][y].setY(height); // Setting the blocks y value here
}
}

return chunk;
}```
And here's my Diamond Square class

Java Code:
```import java.util.Random;

public class DiamondSquare
{
public static double[][] diamondSquare()
{
// size of grid to generate, note this must be a
// value 2^n+1
final int DATA_SIZE = 9;
// an initial seed value for the corners of the data
final double SEED = 900.0;
double[][] data = new double[DATA_SIZE][DATA_SIZE];
// seed the data
data[0][0] = data[0][DATA_SIZE - 1] = data[DATA_SIZE - 1][0] = data[DATA_SIZE - 1][DATA_SIZE - 1] = SEED;

double h = 500.0;// the range (-h -> +h) for the average offset
Random r = new Random();// for the new value in range of h
// side length is distance of a single square side
// or distance of diagonal in diamond
for (int sideLength = DATA_SIZE - 1;
// side length must be >= 2 so we always have
// a new value (if its 1 we overwrite existing values
// on the last iteration)
sideLength >= 2;
// each iteration we are looking at smaller squares
// diamonds, and we decrease the variation of the offset
sideLength /= 2, h /= 2.0) {
// half the length of the side of a square
// or distance from diamond center to one corner
// (just to make calcs below a little clearer)
int halfSide = sideLength / 2;

// generate the new square values
for (int x = 0; x < DATA_SIZE - 1; x += sideLength) {
for (int y = 0; y < DATA_SIZE - 1; y += sideLength) {
// x, y is upper left corner of square
// calculate average of existing corners
double avg = data[x][y] + // top left
data[x + sideLength][y] + // top right
data[x][y + sideLength] + // lower left
data[x + sideLength][y + sideLength];// lower right
avg /= 4.0;

// center is average plus random offset
data[x + halfSide][y + halfSide] =
// We calculate random value in range of 2h
// and then subtract h so the end value is
// in the range (-h, +h)
avg + (r.nextDouble() * 2 * h) - h;
}
}

// generate the diamond values
// since the diamonds are staggered we only move x
// by half side
// NOTE: if the data shouldn't wrap then x < DATA_SIZE
// to generate the far edge values
for (int x = 0; x < DATA_SIZE - 1; x += halfSide) {
// and y is x offset by half a side, but moved by
// the full side length
// NOTE: if the data shouldn't wrap then y < DATA_SIZE
// to generate the far edge values
for (int y = (x + halfSide) % sideLength; y < DATA_SIZE - 1; y += sideLength) {
// x, y is center of diamond
// note we must use mod and add DATA_SIZE for subtraction
// so that we can wrap around the array to find the corners
double avg =
data[(x-halfSide+DATA_SIZE-1)%(DATA_SIZE-1)][y] + //left of center
data[(x+halfSide)%(DATA_SIZE-1)][y] + //right of center
data[x][(y+halfSide)%(DATA_SIZE-1)] + //below center
data[x][(y-halfSide+DATA_SIZE-1)%(DATA_SIZE-1)]; //above center
avg /= 4.0;

// new value = average plus random offset
// We calculate random value in range of 2h
// and then subtract h so the end value is
// in the range (-h, +h)
avg = avg + (r.nextDouble() * 2 * h) - h;
// update value for center of diamond
data[x][y] = avg;

// wrap values on the edges, remove
// this and adjust loop condition above
// for non-wrapping values.
if (x == 0)
data[DATA_SIZE - 1][y] = avg;
if (y == 0)
data[x][DATA_SIZE - 1] = avg;
}
}
}

// print out the data
/*for (double[] row : data) {
for (double d : row) {
System.out.printf("%8.3f ", d);
}
System.out.println();
}*/

/*for (int x = 0; x < data.length; x++)
{
for (int y = 0; y < data[0].length; y++)
{
System.out.println("Double: " + data[x][y]);
System.out.println("Int: " + (int) data[x][y]);
}
}*/

return data;
}
}```

Here's a screenshot of what happens: imgur: the simple image sharer which works, especially with the holes because I can fill them with ores/caves, but do you see how they're clumped together in squares? I want each block to be separated. Plus I don't think I know how to fill the holes with ores/caves, any ideas?