I have been developing a tile game and I implemented Cellular Automata for Random Map generation but it seems to not work properly.
The steps using which I generate a Map are as follows:
*First I generate noise in my Map using the following code:
private static void generateNoise(GameMap gameMap, double threshold, Tile tile) {
for(int x = 0;x < gameMap.getTiles().length;x++) {
for(int y = 0;y < gameMap.getTiles()[0].length;y++) {
double randomValue = Math.random();
if(randomValue < threshold) {
gameMap.setTile(x, y, tile);//Randomly setting the tile
}
}
}
}
*Step 2 I apply the cellular automata Algorithm:
private static GameMap cellularAutomaton(GameMap map, int iterations, Tile tile, Tile base, SpriteLibrary spriteLibrary) {
GameMap tempMap = new GameMap(new Size(map.getWidth(), map.getHeight()), spriteLibrary);
for(int i = 0;i < iterations;i++) {
for(int gridX = 0;gridX < map.getTiles().length;gridX++) {
for(int gridY = 0;gridY < map.getTiles()[0].length;gridY++) {
int neighbours = 0;
for(int x = gridX - 1;x <= gridX + 1;x++) {
for(int y = gridY - 1;y <= gridY + 1;y++) {
if(map.gridWithinBounds(x, y)) {
if(x != gridX && y != gridY) {
if(map.getTile(x, y).isSameTile(tile)) {
neighbours++;
}
}
} else if(!map.gridWithinBounds(x, y)){
neighbours++;
}
}
}
if(neighbours > 4) {
tempMap.setTile(gridX, gridY, tile);
} else if (neighbours <= 4){
tempMap.setTile(gridX, gridY, base);
}
}
}
map=tempMap;
for(int gridX = 0;gridX <tempMap.getTiles().length;gridX++) {
for(int gridY = 0;gridY < tempMap.getTiles()[0].length;gridY++) {
tempMap.setTile(gridX, gridY, base);
}
}
}
return map;
}
For Easy understanding of why am doing the following steps:
GameMap tempMap = new GameMap(new Size(map.getWidth(), map.getHeight()), spriteLibrary);
Saving the map in a temporary map for avoiding logical error.
for(int i = 0;i < iterations;i++) {
Iterating the map no of times.
for(int gridX = 0;gridX < map.getTiles().length;gridX++) {
for(int gridY = 0;gridY < map.getTiles()[0].length;gridY++) {
iterating through every cell of the map.
int neighbours = 0;
Count for the neighbours.
for(int x = gridX - 1;x <= gridX + 1;x++) {
for(int y = gridY - 1;y <= gridY + 1;y++) {
Looping through every neighbour of the current cell
if(map.gridWithinBounds(x, y)) {
if(x != gridX && y != gridY) {
if(map.getTile(x, y).isSameTile(tile)) {
neighbours++;
}
}
}
Checking for the neighbour within the bounds of the Map
else if(!map.gridWithinBounds(x, y)){
neighbours++;
}
Considering the cell outside the map to be the same cell
if(neighbours > 4) {
tempMap.setTile(gridX, gridY, tile);
} else if (neighbours <= 4){
tempMap.setTile(gridX, gridY, base);
}
Setting the current cell according to the number of its neighbours(if neighbours are greater than 4 then it remains same tile else base tile)
map=tempMap;
Setting the map to the temporary map for the next iteration
for(int gridX = 0;gridX <tempMap.getTiles().length;gridX++) {
for(int gridY = 0;gridY < tempMap.getTiles()[0].length;gridY++) {
tempMap.setTile(gridX, gridY, base);
}
}
Clearing the temporary map for next iteration
Now that explained every part of the code.Let me expalin my problem.
Although the algorithm I have implemented is correct(I think). It is not generating the map at all. It is only placing the water tile(given tile) in the corners and the rest of the map is filled with grass tile(base tile).
Also I am getting a "Memory out of bounds exception".But I THINK I can fix it but a solution for that is also highly appreciated.
I think it is only placing it in the corners because is already has neighbours more than 4(the no. of neighbours of the corner is already greater than 4.The number of neighbours for the corner tiles is 5 as we are taking the cells outside the grid the same type by default)
Do you know why this error is occurring(not generating the tiles only generating in the corner). If there is any error in the code please tell.
Thanks for answering.