Get constraints from real life
Often the answer on how to find the right algorithm starts with looking at how these things happen in real life. Have you looked into that? Off the top of my head, I can think of the following:
- Roads are there to connect buildings and other points of interest
- Buildings are placed along existing roads, if possible
- If there is no road, a building is placed in an empty spot and connected to a nearby road via its own road
- Buildings are placed near other buildings that are of interest to their inhabitants: People move to live near their workplaces, food and clothing stores etc.
- Buildings are placed near resources that are necessary for their intended use. E.g. a sawmill is placed near forests, or even in a forest clearing. people need water and food (plants, animals) to live somewhere.
- Buildings are placed far away from other buildings that are detrimental to their intended use, or that they would be a detriment to. E.g. a dyer's shop smells horrible, so is usually not placed in a residential area. Similarly, taverns and restaurants are loud, so residents don't want to live on top of them, but need customers, so need to be near residential areas.
- Some countries have zoning laws that also influence building placement. Usually these are a more formalized way of anticipating what kinds of buildings may be detrimental to each other, or what resources are unique to the area (like, high-quality soil is for fields, not for building parking lots on).
- Buildings are for inhabitants, and their personal style and preferences are reflected in them. E.g. if a population is poor, they're much more likely to share ground (skyscrapers, apartment buildings), if they're more well off, they may get condominioms, if they're rich, they get a standalone villa. If certain groups do not like other groups, they will be less likely to co-habitate. If there is an affinity between certain groups, they may move into similar areas.
Apply them to your topography
Once you have these constraints, you can try to build an algorithm around it. E.g. generate your topography and distribute needed resources around the map (maybe keeping an eye on placing small deposits of the most important resources in the starting area, then larger deposits farther away and from each other). This is where your game's needs and mechanics come into play, of course, but you'll likely also add a random element.
Then build businesses (and their residential buildings) near those resources that use them. E.g. a quarry next to a large mountain. Then add infrastructure needed by them. E.g. a trading post with post office and tavern where they can do business and sell their product, a smithy to provide tools etc.
To decide what goes where, split the map into tiles where you calculate a number for each tile how desirable it is for a certain purpose, using a weighting function. Put the buildings in the most desirable tiles for that kind of building. Add rules like "one trading post can handle 50 businesses or 100 homes", which increase the likelihood of adding another trading post if a city reaches a certain size.
Once you have this, you should get some fairly decent maps. If you notice that maps all end up as unnatural shapes, add penalties to your weighting functions for those shapes, like "if my street ends up right next to another street, -100 desirability", or "if my street crosses itself, -100 desirability" etc. You can always add in a random element to allow this for a more quirky feel, or add other mechanics like "if a crossing has more than N buildings connected to its roads, turn it into a roundabout".
You can even use these constraints to give different maps a different feel, like make a certain country have more mountains in its topography, or have a certain culture build more winding roads, and another prefer straight roads etc. All just by modifying one of your weighting functions.
Simplify
Of course, this approach is too complex for games that aren't trade simulations, but work this out anyway, and see which kinds of buildings make sense for your game, and eliminate the unneeded ones. Then come up with simplified rules like "place cities near a river, a mountain or good soil. 1 building per 100 resources, businesses based on resource type, 10 residential buildings for each full set of food/crafting resource ... or just "1m of river/1sqm of soil can support 10 residential buildings ... whatever makes sense for a game. Still, once you know how much area you have (e.g. no buildings on steep mountain sides), and how many buildings the area can support, just place sets of buildings in that area until it is full (like, 1 business building, 10 residential, 3 infrastructure, or whatever) and connect them with roads.