0

I am procedurally generating a world and for each position in the Tilemap I call this function in order to get the tile type that matches the height:

public static NaturalTile GetNaturalTileByHeight(float height)
{
    SortedDictionary<float, NaturalTile> tilesByHeight = new SortedDictionary<float, NaturalTile>();

    foreach (var tile in NaturalTileTypes)
    {
        if (tile.MaxGenHeight > 0) tilesByHeight.Add(tile.MaxGenHeight, tile);
    }

    foreach (var tile in tilesByHeight)
    {
        if (height <= tile.Key) return tile.Value;
    }

    return null;
}

For each single tile, I have to first create a sorted dictionary so that it's sorted by height. Then, I have to fill the sorted dictionary with the tiles based on height. Finally, I compare the height with each tile in the sorted dictionary, and since it's sorted by height it'll always return the lower-valued tiles first, which makes it work properly.

I feel like this is way too complex, even if it only happens once on world generation.

Any improvement suggestions are greatly appreciated.

caleidon
  • 239
  • 4
  • 13
  • 1
    Using a dictionary isn't super useful here because you don't have discrete values so you can't benefit from the efficiency of a dictionary lookup. You're instead using it in O(n) time (iterating through all items until you find the one you want). You could perhaps define some kind of tree structure which would allow faster lookup (if implemented correctly). – ProgrammingLlama Jan 20 '21 at 09:35

1 Answers1

0

You don't need to sort them separately. Just find the best tile (MaxGenHeight above the argument height, but closest to it) in one loop.

public static NaturalTile GetNaturalTileByHeight(float height)
{
    NaturalTile bestTile = null;
    foreach (var tile in NaturalTileTypes)
    {
        // Is this tile type valid for the given height?
        if (tile.MaxGenHeight > 0 && tile.MaxGenHeight >= height)
        {
            // Is it better than the current best tile?
            if (bestTile == null || tile.MaxGenHeight < bestTile.MaxGenHeight)
            {
                bestTile = tile;
            }
        }
    }

    return bestTile;
}
Antti_M
  • 904
  • 10
  • 20