Generate Buildings in City I am developing a game, its map is based on a 2D city. The city is being generated as string, # are streets, O are buildings.

Here is an example:

#######
#OOOOO#
#OOOOO#
#######
#OOOOO#
#OOOOO#
#######


Now I am replacing the Os with other buildings, by replacing the character with an other. The other buildings are defined in a dictionary, where the identifying character is the key and the value is a number between 1 and 100 which is the propability of the building to replace an O.

Currently I am doing it like this:

// Turn city into charArray
char[] cityChars = renderedCity.ToCharArray();

// Cycle through all KeyValuePairs, ordered by Value ascending
foreach (KeyValuePair&lt;char, byte&gt; kvp in specialBuildings.OrderBy(key =&gt; key.Value))
{
    Random r = new Random(seed);
    // Do the following for all normal buildings in the city
    // If a random seeded number is smaller or equal to the propability of the spawn, change the building into the new one
    cityChars = cityChars.Select(c =&gt; c == 'O' ? (r.Next(0, 100) &lt;= kvp.Value ? kvp.Key : c) : c).ToArray();
}


Is there a more elegant way to do this? In the best case, this would be achieved by using no loops at all, but I am struggling with LINQ a bit.
I think even the simplest solutions can and should be made modular and SOLID. Let's try to refactor your game to give you an idea how to begin...

We start with a city. A city can have different squares where a square is just a simple character/symbol.

class City : IEnumerable&lt;Square&gt;
{
    private readonly List&lt;Square&gt; _squares = new List&lt;Square&gt;();
    public void Add(Square square)
    {
        _squares.Add(square);
    }
    public IEnumerator&lt;Square&gt; GetEnumerator() =&gt; _squares.GetEnumerator();
    IEnumerator IEnumerable.GetEnumerator() =&gt; GetEnumerator();
}


Each square has a position and a symbol. It's abstract so we can derive more concrete types from it.

abstract class Square
{
    protected Square(string symbol, int x, int y)
    {
        Symbol = symbol;
        X = x;
        Y = y;
    }
    public string Symbol { get; }
    public int X { get; }
    public int Y { get; }
    public override string ToString() =&gt; Symbol;
}


You seem to have two types currently. A building and a street so here they are:

abstract class Square
{
    protected Square(string symbol, int x, int y)
    {
        Symbol = symbol;
        X = x;
        Y = y;
    }
    public string Symbol { get; }
    public int X { get; }
    public int Y { get; }
    public override string ToString() =&gt; Symbol;
}

interface IUpgradable 
{ 
    void Upgrade();
}

abstract class Building : Square, IUpgradable    
{
    protected Building(string symbol, int x, int y, int level)
    : base(symbol, x, y)
    {
        Level = level;
    }
    public int Level { get; private set; }
    public void Upgrade()
    {
        Level++;
    }
    public override string ToString() =&gt; "O";
}

class School : Building
{
    public School(int x, int y, int level) : base("H", x, y, level) {}
}

class Hospital : Building
{ 
    public Hospital(int x, int y, int level) : base("S", x, y, level) {}
}

class Street : Square
{
    public Street(int x, int y) : base("#", x, y) { }
    public override string ToString() =&gt; "#";
}


Buildings can be upgraded thus the Upgrade method which increases its level. Each upgradable type implements the IUpgradable interface then so you can even filer on that.

I don't know how you generate your map but for the sake of this example I did it by hand:

Here's a simple city:

// ###
// #H#
// ###
var city = new City 
{
    new Street(0, 0), new Street(1, 0),new Street(2, 0),
    new Street(0, 1), new Hospital(1, 1),new Street(2, 1),
    new Street(0, 2), new Street(1, 2),new Street(2, 2),
}


Next we want to upgrade some buildings (I might have the condition for upgrading wrong but it should just demostrate the general idea)

Random r = new Random(seed);

// helper encapsulating the can-upgrade logic
var canUpgradeBuilding = new Func&lt;Building, bool&gt;(b =&gt; b.Level &lt;= r.Next(0, 100));

// upgrading buildings
foreach (var b in city.OfType&lt;Building&gt;().Where(canUpgradeBuilding))
{
    b.Upgrade();
}