LunarMongoose
King
So I'm guessing you really didn't just do to create the vacuum? Because I would totally do that and screw any more complicated approach.
The problem with that is that processCivics() is a very expensive function. It performs a ton of value assignments AND loops over the whole BuildingClass list which is huge (among other loops). This will slow down the game significantly when you're calling processCivics() up to 10 times per AI_doCivics() call (to remove up to 5 existing civics then restore them once calculations are done), and you're probably calling AI_doCivics() once per AI player every turn.
The system I've set up modifies AI_getH/HWeight() directly to start with the health and happiness values for each city it's considering as if all civics were off: basically "int iCityHappy = pLoopCity->happyDifferenceWithoutCivics()". This function mostly just reads off stored values, and the ones it does compute on the fly are simple if/else things that don't loop over any long lists. It will run MUCH faster than what you were proposing.
The PROBLEM with it, which I just realized before I went to sleep last night, is that you can't update health/happiness on a per-civic-category basis as you select a civic in each category as you go... But I don't think your approach is a good idea either - it will simply be too slow, especially when you consider we're already slowing things down a bunch by making it look at all an AI's cities instead of just the first 7... Meh.
As for the military happiness: count your units with UNITAI_CITY_DEFENCE to find out how much happiness you will gain. Or if there are more unitais that mostly stay in cities, add them too, total units is too much though, you can't count on them staying in cities.
Checking UNITAI_CITY_DEFENSE is a good idea... I was just going with isMilitaryHappiness() which is the XML value that defines whether a unit can provide Monarchy happiness (or just plain elimination of Fear For Safety effect regardless of civics). I was then gonna scale it by some number of to factor in the fact that not all units would be in their own cities at all times.
The problem with what you're suggesting Roland, is you're trying to come up with exact precise perfect values for the weight and that's not a good idea. The speed of this code is important, the stats of a civ empire change quickly as turns pass anyway, and a good estimate is all you need or want here I'm pretty sure. There are "good estimate" values all OVER both the vanilla and BBAI code... if you wanted to start turning them all into extremely-accurate numbers we'd be here discussing this all year heh.
Basically I need a formula of the form: some sort of unit count, times some sort of scale coefficient to factor in the logistical realities of managing an army, divided by some sort of city count.
Not sure about step 7 yet. What should be the threshold?
single cathegory condition: If at least one civic value is 120%+ of the active civic's vacuum value, and sum new > sum old (non-vacuum) then revolt to new civics combination.
If that fails, check the sums' relative difference. if new * (100 + threshold) > old * 100, revolt.
threshold value = (3*5/total cathegories)% + (number of civic changes*5/total cathegories)%?
1/5: 4% (20% of average cathegory value)
2/5: 5% (12,5% per cath)
3/5: 6% (10% per cath)
This should not make the AI more likely to revolt than normally but it should make it easier to change more than one civic in one go.
Nice work Fuyu, that's exactly what I needed and didn't want to have to come up with myself lol. Doesn't matter til I decide what to do about the H/H by civic category issue though...