0

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.

  • Yes, that "Memory out of bounds exception" (whatever it actually is; do you mean an ArrayIndexOutOfBoundsException or an OutOfMemoryError?) likely is relevant. It would be helpful to know where it happens, and why. Have you tried running your code in a debugger and telling it to stop when that exception is thrown? That would let you examine your variables and call stack and see what the code is trying to do that causes the exception. Also, single-stepping through your code in a debugger can generally be very useful for understanding how it works (or why it doesn't). – Ilmari Karonen Oct 20 '21 at 16:55
  • Oh yes it is the OutOfMemoryError.Also I tried single stepping my code and when I removed the "map = tempMap" line it didn't show the outOfMemory error. But I need to somehow save the data(tiles and their position)in the map for the next iteration and clear the tempMap.If the following is not possible.is there any other simple way for map generation? – Pro Gramers Oct 23 '21 at 02:57
  • If you're getting an OutOfMemoryError, that means you either have an outright memory leak (i.e. you're keeping a chain of references to an ever-increasing number of objects that are never released) or you keep growing some object forever. (Or you just straight up try to create a ridiculously big array or something, but it doesn't seem like you're doing that.) You haven't shown the GameMap constructor, but is it possible that each new map you create is bigger than the previous one? That would certainly do it. – Ilmari Karonen Oct 23 '21 at 09:30
  • I was able to successfully solve the OutOfMemoryError.I changed the line "map = tempMap" to a for loop that sets tile(in the tempMap) to the same position in the map. no problem in the GameMap class.I guess it was dong it because it was constantly setting the map to tempMap after every iteration.Now that its fixed the only problem remains in not generating the map.I tried many things and got varying results but I can't totally explain it here.Would you like me to edit the question so that I can explain it,easily?@IlmariKaronen – Pro Gramers Oct 26 '21 at 12:51
  • Yes, you should probably rewrite the question to focus on your new problem. (Either that, or delete it and ask a new question.) Before you do that, you might also want to check out our help center pages on [how to ask a good question](/help/how-to-ask) and specifically [how to create a minimal, reproducible example](/help/minimal-reproducible-example). Taking the [tour] isn't a bad idea, either, if you haven't done it already. – Ilmari Karonen Oct 26 '21 at 13:36
  • Sorry it has been so many days but I have been busy irl for sometime but the question is almost ready but I have to do some more testing before uploading . It might take a day or two .thanks . – Pro Gramers Nov 04 '21 at 12:16

0 Answers0