Better City Sites AI

For one thing, it doubles the time it takes me to test a release. Because of the difference in availability of ice, I try to do all the autoplays once on arrakis and once on archipelago. If it's useful, fine, but cutting it would make releases a little easier.

I still think it is maybe worth keeping Archipelago, just for variety. It would be nice to force Arrakis to be the default option though.

I checked Arrakis.py and indeed it has its own starting plot value function mostly making distance checks (which seems to fail often).

I knew this was the case. If we don't specify a starting plot function then presumably both mapscripts will use the new logic you are making.
 
The reason that I had re-created the starting plot code was for PerfectWorld. It had large areas of bad land, and the default code only really looked at local values, so you could start on a good site, but have nowhere to expand. This code helped to alleviate that problem by taking into consideration possible later city sites. All this is probably unnecessary in Arrakis.py.
 
I autoplayed 3 games and printed out some nice statistics about our current situation.

Map settings:

Map script: Arrakis.py
Map size: Standard
Game speed: Quick
Players: 7
Pangaea style

Game options:
only "no barbarian" is checked

Victories:
All but last two

Statistics always taken on turn 250/330



As you can see we have problems with the average population (only 10). There are also a lot of small cities, even in late game. Some of them were maybe just founded recently. :dunno:
Be careful with "Cities not growing"-line. No growth doesn't automatically indicate a bad location, but also could result from misplaced improvements.

Mesa tiles per city: We already guessed it, the amount of mesa tiles is one of the key factors to get a good city location. Similar situation in the "Food bonus per city"-line.

Desert tiles per city: This is interesting. Having a lot of desert tiles inside a bfc dramatically reduce the quality of a city site. I think this is a good argument for outsourcing spice harvest outside of the bfc. :)

Mesa shared/Food bonus shared: As you can see there isn't any relation between tiles shared with other cities and the size of a city. This disproves Ahriman claiming shared tiles are a major reason for cities not growing.

Another problem I run into while coding the statistics is, that spice is counted as a regular commerce bonus, making it completly overrated.

So my first steps in improving ai_foundvalue will be:
- writing a true algorithm to count mesa tiles available for wind traps
- dramatically increasing values for peaks (=mesa)
- rejecting all city sites with less than 2 food bonuses
- excluding spice bonus from found value
- giving a small penalty for desert(=water) tiles
- removing all checks related to coastal/area
- increasing the malus for founding cities too close
- rejecting city home plots habouring bonuses

If you want print out statistics for yourself, here is a modified Dunewars.py. Copy it to "DuneWars/Assets/Python". It is working with 1.6.1 and 1.6.2. In turn 250 a file "betterCityAI.log" will created in your bts folder.
 

Attachments

  • DuneWarsCityAIStatistics.rar
    13.5 KB · Views: 92
  • citysites.jpg
    citysites.jpg
    102.5 KB · Views: 196
I've noticed that the AI wastes bonuses by building cities on top of them, rather than close to them and then building the improvement. Can we also stop it from doing that?
 
I've noticed that the AI wastes bonuses by building cities on top of them, rather than close to them and then building the improvement. Can we also stop it from doing that?

True, I noticed that too. It is easy to avoid.
 
So my first steps in improving ai_foundvalue will be:
- writing a true algorithm to count mesa tiles available for wind traps
- rejecting all city sites with less than 2 food bonuses

I am not sure that a true algorithm for mesas is worth the trouble. I have thought about it, and it is clearly possible, but I suggest that an approximation is enough. I would suggest simply counting the mesa tiles and dividing by 4.

Fury Road also has very limited food resources available. When I first wrote the mapscript, there were many cases where the starting location was very poor. So what I did for the starting location was add food bonuses in the mapscript, rather than rejecting the start location or displacing it a long distance. So for start locations, maybe consider adding food bonuses instead of rejecting or displacing the location. This may be why the mapscript sometimes generates start locations for two civs which are very close together.
 
I am not sure that a true algorithm for mesas is worth the trouble. I have thought about it, and it is clearly possible, but I suggest that an approximation is enough. I would suggest simply counting the mesa tiles and dividing by 4.

I think it is worth the trouble. Having 4 mesa tiles clumped together is something completly different from having 4 single mesa tiles.

Fury Road also has very limited food resources available. When I first wrote the mapscript, there were many cases where the starting location was very poor. So what I did for the starting location was add food bonuses in the mapscript, rather than rejecting the start location or displacing it a long distance. So for start locations, maybe consider adding food bonuses instead of rejecting or displacing the location. This may be why the mapscript sometimes generates start locations for two civs which are very close together.

Well, I am currently working on general city sites, not starting locations. Adding new bonuses isn't an option...
 
Having 4 mesa tiles clumped together is something completly different from having 4 single mesa tiles.

That is true ... but you can no longer have clumps of 4 mesa tiles. I am not saying it is completely unimportant, but you could leave the exact algorithm for later so that we can start using the new code sooner.
 
One difference between vanilla and DW is that vanilla has alot of invisible resources, so if the AI assigns value to things like aluminum in ancient times, it's kinda cheating, so they have this code to avoid that.

In DW you have these resources that develop through the ages, so the AI won't see it's full potential.

Good point, but a different one than I was thinking of. I suppose that considering the value of crystal, which is initially invisible, would cause selection of one city site over another. But water (food) yield for a particular improvement now increases quite a lot during the game due to tech. My point was I don't think we need to model this increasing yield in order to get the right city sites.
 
Good point, but a different one than I was thinking of. I suppose that considering the value of crystal, which is initially invisible, would cause selection of one city site over another. But water (food) yield for a particular improvement now increases quite a lot during the game due to tech. My point was I don't think we need to model this increasing yield in order to get the right city sites.

Well, if it's picking the wrong sites, I figure there has to be something that is competing with the food. I think the AI actually assigns numeric values according to the yield types, and it's fairly simple, like too simple to reflect what is really needed. Basically, a plot gets a bonus to it's value if it can feed itself, but if you have one plot that can feed itself and a whole bunch of production plots that can't, it still gets factored in even though you can't work all those production tiles due to lack of food.

Those yield values are defined somewhere, you might get better results if you emphasize food. The default emphasizes production actually.
 
I don't really understand the S/M/L. Are there averages for cities in particular population ranges?

Desert tiles per city: This is interesting. Having a lot of desert tiles inside a bfc dramatically reduce the quality of a city site. I think this is a good argument for outsourcing spice harvest outside of the bfc.

I disagree with your interpretation. Obviously, more desert tiles means smaller city size, because fewer water sources - but it may have more spice access. But that does not necessarily mean worse city, or that the city shouldnt' have been built.
All it says is that.... cities with fewer land tiles have less water. Which is obvious.
And it certainly isn't an argument for pushing spice harvesting outside culture.

Mesa shared/Food bonus shared: As you can see there isn't any relation between tiles shared with other cities and the size of a city. This disproves Ahriman claiming shared tiles are a major reason for cities not growing.

I diagree with your interpretation.
Across your 3 games, looking at the totals, roughly 1/3 of mesa tilse and 1/5 of water resources are shared with other cities.

That is a large amount. This means that an AI city is getting very roughly 25% less water income per city than would a human player who did not overlap water sources.

Which suggests that overlapping resources is a big reason why AI cities are smaller.

Another problem I run into while coding the statistics is, that spice is counted as a regular commerce bonus, making it completly overrated.

Yes, I have commented on this before. Spice should be ignored when choosnig city placement, because of its transient nature. This is one fo the big reasons why the AI places cities too close to the coast, to try to maximize spice access.

I would suggest simply counting the mesa tiles and dividing by 4.
Why divide by 4? I would multiply by 2/3. On average, 3 mesas are surely worth 2 dew collectors. Remember that mesa has a base +1 water yield....

And like David says, we don't get 4-mesa clumps.

Those yield values are defined somewhere, you might get better results if you emphasize food.

This is the most important factor IMO.
 
IWhy divide by 4? I would multiply by 2/3. On average, 3 mesas are surely worth 2 dew collectors. Remember that mesa has a base +1 water yield....

Koma13 had proposed spending some time to implement code which correctly interprets the windtrap spacing rule and finds the optimal location/number of windtraps for a given city site. I was proposing that instead of solving this hard placement problem, simply approximate the number of possible windtrap sites as (number of mesa plots) / 4. I was not discussing any tradeoff relative to dew collectors, just counting the number of windtraps.

The 1/4 number is what you would get, if you had the one plot spacing and a region which was 100% solid mesa. (Try drawing a tic-tac-toe type board and filling it in; it comes to exactly 1/4.) But I thought of that before declumping(?). I guess the best approximation counting declumping is 1/2. Draw solid vertical lines of mesa. Now densely populate windtraps. You can put one windtrap every two plots of mesa, so, 1/2. Does that make sense?

Any "optimal" solution has to take into account edge effects; if two city BFC touch, and there is a windtrap for one city at a border plot, then the other city has fewer possible windtrap sites. I think optimally solving this is hard, which is why I recommended the approximation. It reduces development time with minimal loss of accuracy.
 
I was proposing that instead of solving this hard placement problem, simply approximate the number of possible windtrap sites as (number of mesa plots) / 4. I was not discussing any tradeoff relative to dew collectors, just counting the number of windtraps

I undersatnd that, but you can already get more than 1 windtrap per 4 mesas, on all mapscripts.
You can at most get 2 per 3, and on average probably 1 per 2. At worst you can get 1 per 3 (an L shape mesa).
If this is purely for windtraps per mesa (ignoring the base yield of the mesa) then 1 per 2 is probably right.
If its for mesa tiles vs other water sources, then 2/3 is probably right.

Implicitly how you value mesa tiles (and how many windtraps you credit them with) affects the tradeoff you consider vs say dew collector resources: should I found in location A, or should I shift right 1 tile to location B, losing 1 dew collector but gaining 3 mesas. The answer to this should unambiguously be "yes", but I worry with your method of 1 windtrap per 4 mesa that the AI's answer could be "no".

I agree with the approximation (fully optimal is hard), but 1/2 is better than 1/4.
 
I thought a little bit about how to make a simple replacement for the AI_foundValue function which decides where initial cities and later settler sites should be. As we have discussed the existing function is over a thousand lines of mostly undocumented code. Here is what I propose to compute the value of a plot.

Score computation

If a plot is a valid city site (not in enemy cultural borders, not too near another city, not ocean, not mesa, *not on a visible resource*) then loop over all the plots in its BFC to total up the plot values.

In the BFC loop, skip a plot if it belongs to any existing city BFC or enemy cultural borders. Otherwise a plot's value is the sum of one number based on resource plus one number based on terrain:

Resource:
50 if it has a groundwater resource
30 if it has a water plant resource (sword grass, etc)
10 if any other visible resource except spice

Terrain:
30 if mesa
5 if polar
3 if graben or polar desert waste
2 if rock or desert waste
1 if rugged

If there is any visible crystal in the BFC, add 100. If there is any nitrate in the BFC, add 100. If there is any ice in the BFC, add 100.

Are there other things to consider? This seems pretty simple, perhaps too simple.

Starting locations

For starting locations on arrakis, we need to make sure they are equally spaced around the circle, not too close to the center. So we can do the following steps.

1. Assign each plot to a sector, where the sector is shaped like a pie slice, where the span of the pie slice is 360 degrees divided by the number of civs. So for 9 civs, each one gets a 40 degree slice. Exclude the polar region.

2. For each sector, count up the *total* score based on resources and terrain.

3. Sort the sectors by lowest score first. Picking a site in one sector will eliminate a number of possible sites in other sectors because they are too close; so we want to pick sites in the poorest sectors first.

4. Initially we want to try a minimum separation between start sites of 16 plots.

5. For each sector in score order, remove potential sites which are too close to a chosen site in an earlier sector, then pick the best site. If a sector has no potential sites due to distance, scrap all the sites for all the sectors and restart, decreasing the minimum separation by 2.

Does this seem reasonable for start position selection?

Colony sites

For later colony sites, there is an additional complication that we should not consider two possible sites which are adjacent to each other. That is, if we have one possible site, we must temporarily pretend there is a city there, and recalculate the scores for other sites with this assumption. This is one of the things which leads to extra complexity in the current AI_foundValue, and I have not carefully thought out the best way to do this yet. Distance from the current capitol should also be a factor.
 
Ok, here are my observations from tests I made in the last weeks:

1)
The value of AI_foundvalue doesn't teach the ai where to found cities :eek:. It teachs the ai where to found cities first. Think about the consequences, especially for ai autoplay results!

2)
As a human player I often have to decide whether I want to found one good city or two okayish cities. The ai isn't capable of this. It will always decide having one good city.

3)
The only thing preventing ai in vanilla civ4 of wasting too much terrain inbetween cities is the distance check resulting in cites placed close together

4)
AI city placement in vanilla civ4 isn't more clever than in dw. The "only" difference is, that in dw there are much more bad possible city sites (because of selective yield distribution)
 
1) Not quite sure I entirely understand this. Do you mean that the AI will found first using this value, and then still fill in all availble empty space with junk cities?

2) As a human player in this mod, building few good cities tends to be a better strategy than in vanilla, so this is not a huge problem. I would much prefer that the AI err towards building fewer, better cities than the status quo, where it founds many, bad cities.

3) Ugh. Unfortunate. Can you add some kind of block that will prevent the AI from building a city in a location unless its foundvalue is at least X?

4) Yes, this is true.... but it still means that AI city placement is more important here than in vanilla.
 
The value of AI_foundvalue doesn't teach the ai where to found cities :eek:. It teachs the ai where to found cities first. Think about the consequences, especially for ai autoplay results!

I assume that if there are several city sites, one with foundValue=100, another with 150, and another with 200, then the first settler will be sent to the 200 site. It means that the distance function must be calibrated carefully so that it trades off correctly between a moderate location nearby, and an excellent location further away.

Or, did you mean something more than that?
 
Top Bottom