2D: Best way to group a type of tile based on their neighbors similar type?

Hello,

I currently have a tilemap structure setup using a multi-dimensional array.

TDTile[,] _tiles = new TDTile[50,50];

On this map I have a bunch of trees, and I wanna group them all by pairs of 4.
This is working, but it is leaving residue trees behind, like you can clearly see nice groups of 4 or bigger tree clusters, but occasionally there are a couple tree’s spread around the map that are not grouped, so in a pair, or just a single tree every here and there…

Is there a better way I can group my tiles?

Example view:

121786-screenshot-1.png


This is my current approach:

private List<TDTile> GetNeighbors(int x, int y)
{
    Vector2Int[] positions = new [] 
    {
        new Vector2Int(x-1, y),
        new Vector2Int(x+1, y),
        new Vector2Int(x, y - 1),
        new Vector2Int(x, y + 1),
        new Vector2Int(x + 1, y + 1),
        new Vector2Int(x - 1, y + 1),
        new Vector2Int(x + 1, y - 1),
        new Vector2Int(x - 1, y - 1),
    };

    List<TDTile> neighbors = new List<TDTile>();
    foreach (var pos in positions)
    {
        if (IsInRangeOfMap(pos.x, pos.y))
        {
            neighbors.Add(_tiles[pos.x, pos.y]);
        }
    }

    return neighbors;
}

private void GroupTilesBy(string type, int minAlive)
{
    for (int x = 0; x < Width; x++)
    {
        for (int y = 0; y < Height; y++)
        {
            if (_tiles[x, y].Type == type)
            {
                var neighbors = GetNeighbors(x, y)
                    .Count(f => f.Type == type)

                neighbors++; // Count our own tile in aswel

                if (neighbors < minAlive)
                {
                    _tiles[x, y] = _db.GetDefaultTile();
                }
            }
        }
    }
}

I could do something cheeky like this after grouping, to solve the problem:

for (int x = 0; x < Width; x++)
{
    for (int y = 0; y < Height; y++)
    {
        if (_tiles[x, y].Type == type)
        {
            var neighbors = GetNeighbors(x, y)
                .Count(f => f.Type == type)

            if (neighbors == 0)
            {
                _tiles[x, y] = _db.GetDefaultTile();
            }
        }
    }
}

But I feel like I’m just missing something, that I’m doing wrong in the actual algorithm.

Open to suggestions about improvement.

Thanks in advance…

Kr, Shady.

Take a look at Procedural Map generation tutorial, Walls and Rooms - Unity Learn this video focuses on the Flood Fill algorithm which will help you identify the tiles and their neighbours for adding/removing these