View Full Version : Bug causing war with distant civs.


Nacht
May 31, 2007, 05:05 AM
I've found a bug in Better AI that could explain why AI's tend to pick distant enemies far too often.

it's about this code:


if (iCount > 0)
{
//cross up to the entire map to kill the only other foe
//be more picky if there are more foes...
int iTeamCount = GC.getGame().countCivTeamsAlive();
int iMaxDistance = GC.getMapINLINE().maxPlotDistance();

if (iSameAreaCount > 0) //preserve sanity on islands...
{
iMaxDistance *= 4;
iMaxDistance /= (2 + iTeamCount);
}

return max(1, (iMaxDistance - (iDistance / iCount)));
}



that is added in Better AI to CvTeamAI::AI_calculateCapitalProximity which is used to determine the best victim for the next war. It's a score so higher values are better. It basically returns maximum distance minus capital distance in stock Warlords.

consider this map:
http://members.chello.nl/plombaar/rep.JPG

The results Isabella gets in Warlords 2.08:

Churchill: 74
Alexander: 72
Stalin: 57
Tokugawa: 64
Ragnar: 46
Bismarck: 34
Huayna Capac: 29
Player (Egypt): 19
Hannibal: 14



with Better AI rev. 368 everyone on her own continent gets vastly lower scores:

Churchill: 14
Alexander: 12
Stalin: 1
Tokugawa: 4
Ragnar: 46
Bismarck: 34
Huayna Capac: 29
Player (Egypt): 19
Hannibal: 14



with Better AI with iSameAreaCount > 0 changed to iSameAreaCount == 0 war on other landmasses is highly discouraged .

Churchill: 74
Alexander: 72
Stalin: 57
Tokugawa: 64
Ragnar: 1
Bismarck: 1
Huayna Capac: 1
Player (Egypt): 1
Hannibal: 1

Melhisedek
Jun 03, 2007, 03:26 AM
Great find mate :) Where should I make the change or is it not that simple?

Yakk
Jun 04, 2007, 10:45 AM
return max(1, (iMaxDistance - (iDistance / iCount)));

iDistance would be distance between you and them.
iCount would be # of civilizations.

if (we are on different islands)
++ consider the map to be 4/(2+team_count) times larger.


that is a strange bit of math -- why are we factoring in the number of teams here?

If we eliminate that, and have it scale the bonus by a factor when you are on the same island:


if (iSameAreaCount == 0) //preserve sanity on islands...
{
int iDifferentContinentPenalty = 4;
iMaxDistance /= iDifferentContinentPenalty;
iDistance /= iDifferentContinentPenalty;
}

and voila, the scores of people on different islands will be 1/4 as high, instead of being always 1 no matter how far away they are.

Yakk
Jun 04, 2007, 07:14 PM
Alternatively:


if (iSameAreaCount > 0) //preserve sanity on islands...
{
// we are on the same continent.
// Bonus grows for this with the number of teams alive
// when there are only 2 teams alive, the bonus falls to 0
int iSameContinentBonus = iMaxDistance*(iTeamCount-2)/2;
iMaxDistance += iSameContinentBonus;
}