[BNW] The Bomb and AI Decision Making

dexters

Gods & Emperors
Supporter
Joined
Apr 23, 2003
Messages
4,182
Location
Canada
So I've noticed the AI is 'thinking' about how to use their A-Bombs; While I do still see irradiated territory, they seem somewhat more hesitant to use it at war.

In this case, I DoW Venice late game just to knock him off as a challenger. At this point Venice had accumulated a vast stockpile in cash and I had up to this point been bribing Mongolia. However, the Mongols were becoming weaker every moment as I myself was attacking it from the other direction.

So it came to a point where I was finally ready to declare war on Venice. At this point Genghis had already nuked one of his cities, and I see an A-Bomb stationed at one of Venice's border cities, right next to the 3rd city from my capital (very production/prime target)

I also made the mistake(?) or moving 10 bombers there throughout my buildup, hoping to take the border city with the A-bomb in 1 turn.

I DoW, start bombing, but realize later game city defences (130+) meant that my bombers weren't giving out enough damage (much less than I remembered from before) so even with 10 bombers, I could not get the job done. To make matters worse, the city was 3 tiles in from the nearest border point, 3 full tiles of hilly terrain and I had not prepped a road so my artillery could not provide 1st turn support and my Infantry actually could not have reached the city gates and attacked on the same turn, making my 1 turn gambit void.

At this point I expected the worse. He would nuke me in retaliation and wipe out half my airforce (the other half I had stationed at another city for my attack on the real prize, Venice itself) and crippled one of my bigger cities.

But in the inter-turn nothing happened. I realized later that Instead of using it, he retreats the bomb from his damaged border city back to his capital. And there it sat, as I took the next 3 turns killing his artillery and units, surrounding Venice, bombing it, and finally moved in artillery support to finish it off. Venice fell with the A-bomb still inside it.

This behavior puzzles me. Is the AI scared of M.A.D? I had at this point built something like 10 A-Bombs, and I was the first to build the bomb, as evidenced by'Afraid' attitudes of several of the AIs. So conceivably he the exchange would be 10-1 in my favour and he would be utterly destroyed.

The questions are
- Why was Genghis willing to use his bomb vs. Venice but Venice afraid to use his against me?
- Does nuclear parity and MAD now come into play? Perhaps an AI at a clear disadvantage may think twice?
- Why did he not use his bomb against Genghis, who had nuked him and was still at war with him? (possible explanation is I took the closest and biggest Mongol cities and more or less surrounded Venice on 3 sides-- he might still have been able to Nuke a 3rd tier city but the new Mongol capital is surrounded out of range of his Abomb)

I also wondered if Venice would have held back his bomb had I nuked him as my first strike, or had nuked someone as my first strike. In this game, I built the 10 bombs but never used it so I had a 'clean' diplomatic record.
 
Different AIs have different flavors on how likely they are to use a nuke. Gandhi is the highest at 12. Genghis is at a 7 and Enrico is at a 4. He isn't likely to use it at all.
 
Different AIs have different flavors on how likely they are to use a nuke. Gandhi is the highest at 12. Genghis is at a 7 and Enrico is at a 4. He isn't likely to use it at all.

I thought those flavours only determine how many/often they build the bomb. I woulda thunk once they build one they'd use it.

Interesting.
 
I'm yet to see an AI use nukes on units, not just cities. I've only experienced being nuked twice in one game. Good thing my targeted cities were puppet states, along with a puppeted capital.

I also had a case in my previous Shoshone game where I built a nuke, most other civs were afraid, yet some of them had nukes as well. So there could be an element of M.A.D in AI.
 
Different AIs have different flavors on how likely they are to use a nuke. Gandhi is the highest at 12. Genghis is at a 7 and Enrico is at a 4. He isn't likely to use it at all.


Ghandi is highest ? Really ? O.o

Hopefully he's lowest on producing them then, because otherwise that just seems messed up :D
 
Ghandi is highest ? Really ? O.o

Hopefully he's lowest on producing them then, because otherwise that just seems messed up :D

No he is at a 12 for producing and using them, which is WAY higher than anyone else. Its a running gag with the devs.
 
Yeah, looks like it's been a change splitting out produce/use of Nukes which is nice to see (their expanding of the flavours) ;
This is why I was working under those old assumptions.

I went back to Bibor's old Diplomacy by the Numbers spread and someone had updated it with an updated list.

Here's the new spread that's been making the rounds, I haven't checked XML to confirm, but I assume everything's correct.

http://i.imgur.com/Hm6la2R.png
 
From CvMilitaryAI.cpp:

Code:
//
	// Operation vs. Other Civs
	//
	// If at war, consider launching an operation
	if(IsUsingStrategy(eStrategyFightAWar))
	{
		// check nuke launches
		// Loop through each enemy
		for(iPlayerLoop = 0; iPlayerLoop < MAX_MAJOR_CIVS; iPlayerLoop++)
		{
			eLoopPlayer = (PlayerTypes) iPlayerLoop;

			// Is this a player we have relations with?
			if(eLoopPlayer != m_pPlayer->GetID() && m_pPlayer->GetDiplomacyAI()->IsPlayerValid(eLoopPlayer))
			{
				bool bLaunchNuke = false;
				// only evaluate nukes when we have nukes and we've declared war on someone
				if (m_pPlayer->getNumNukeUnits() > 0 && GET_TEAM(m_pPlayer->getTeam()).isAtWar(GET_PLAYER(eLoopPlayer).getTeam())) 
				{
					// they nuked us, so we can nuke them.
					if (m_pPlayer->GetDiplomacyAI()->GetNumTimesNuked(eLoopPlayer) > 0)
					{	
						bLaunchNuke = true;
					}
					// if we already nuked them, uhhh, keep it up!
					else if (GET_PLAYER(eLoopPlayer).GetDiplomacyAI()->GetNumTimesNuked(m_pPlayer->GetID()) > 0)
					{
						bLaunchNuke = true;
					}
					else 
					{
						bool bRollForNuke = false;
						WarProjectionTypes eLastWarProjection = m_pPlayer->GetDiplomacyAI()->GetLastWarProjection(eLoopPlayer);
						WarProjectionTypes eCurrentWarProjection = m_pPlayer->GetDiplomacyAI()->GetWarProjection(eLoopPlayer);
						if (eCurrentWarProjection == WAR_PROJECTION_DESTRUCTION)
						{
							// roll every turn
							bRollForNuke = true;
						}
						else if (eCurrentWarProjection != WAR_PROJECTION_UNKNOWN && eCurrentWarProjection != NO_WAR_PROJECTION_TYPE && 
							eLastWarProjection != WAR_PROJECTION_UNKNOWN && eLastWarProjection != NO_WAR_PROJECTION_TYPE && 
							eCurrentWarProjection < eLastWarProjection)
						{
							// roll for nukes!
							bRollForNuke = true;
						}

						if (bRollForNuke)
						{
							int iFlavorNuke = m_pPlayer->GetGrandStrategyAI()->GetPersonalityAndGrandStrategy((FlavorTypes)GC.getInfoTypeForString("FLAVOR_USE_NUKE"));
							int iRoll  = GC.getGame().getJonRandNum(10, "Roll to see if we're going to nuke!");
							int iRoll2 = GC.getGame().getJonRandNum(10, "Second roll to see if we're going to nuke!");
							if (iRoll < iFlavorNuke && iRoll2 < iFlavorNuke)
							{
								bLaunchNuke = true;
							}
						}
					}
				}

				if (bLaunchNuke)
				{
					RequestNukeAttack(eLoopPlayer);
				}

			}
		}

Basically, the AI will launch a nuke if:

1. The enemy civ has already nuked them (first IF test)

2. This civ has already nuked the enemy (keep the momentum, second IF)

3. The war is going very badly for them (WAR_PROJECTION_DESTRUCTION means they are going to loose the war, third IF)

4. The war is deteriorating for them (current war projection is worse than previous, fourth IF)

After the decision to launch OR roll for nukes has been taken, the roll comes, and it is a double roll, where both rolls have to be less than the flavour for using nukes of the civ.

In other words, it has become a "weapon of last resort" for the AI, as it should be.
 
Since when can you get at the source code for the AI? That's neat.

And if I may attempt to explain it better, from that snippet:

If you've nuked them -> they will retaliate, nuke flavour no longer matters

If they've already nuked you -> they will continue, nuke flavour no longer matters

If the war is deteriorating or they are losing badly -> roll for chance to nuke based on nuke flavour

The roll is (x*x)/100 = chance to nuke, where x is their nuke flavour. Enrico at 4 would have a 16/100 chance each turn to decide to nuke (and of course the flavour itself is random, if he rolled low it could be 4/100 chance).
 
I'm yet to see an AI use nukes on units, not just cities.

I've noticed the same thing and this should be changed. WWIII will probably have a lot of small tactical nukes that are used on the battlefield. Major population centers would probably be left alone, at least initially unless if things get out of control.
 
Waw, nice find for the AI coding.

So it's not hard coded into the game? That's actually very interesting :p
 
From CvMilitaryAI.cpp:

Basically, the AI will launch a nuke if:

1. The enemy civ has already nuked them (first IF test)

2. This civ has already nuked the enemy (keep the momentum, second IF)

3. The war is going very badly for them (WAR_PROJECTION_DESTRUCTION means they are going to loose the war, third IF)

4. The war is deteriorating for them (current war projection is worse than previous, fourth IF)

After the decision to launch OR roll for nukes has been taken, the roll comes, and it is a double roll, where both rolls have to be less than the flavour for using nukes of the civ.

In other words, it has become a "weapon of last resort" for the AI, as it should be.

Thanks. Can you clarify what the first if statement is testing?

Code:
if (m_pPlayer->getNumNukeUnits() > 0 && GET_TEAM(m_pPlayer->getTeam()).isAtWar(GET_PLAYER(eLoopPlayer).getTeam()))

I also assume the if statements are independent of each other ; ie: the AI could still launch if its losing,but hasn't yet been nuked first or hasn't already nuked.
 
Thanks. Can you clarify what the first if statement is testing?

Code:
if (m_pPlayer->getNumNukeUnits() > 0 && GET_TEAM(m_pPlayer->getTeam()).isAtWar(GET_PLAYER(eLoopPlayer).getTeam()))

I also assume the if statements are independent of each other ; ie: the AI could still launch if its losing,but hasn't yet been nuked first or hasn't already nuked.

That just says that they will only decide whether or not to nuke you if they actually have nukes and they're at war with you.
 
That just says that they will only decide whether or not to nuke you if they actually have nukes and they're at war with you.

Correct.

As for the other question, the if-elseif-else sequence is mutually exclusive; that is, ONE of the IFs will be matched, and only one. The first IF checks for "having been nuked"; if that fails, then it checks for "us having already nuked this enemy", and if that also fails, then it goes to the "default" else where the roll or not roll logic is processed.

In other words, yes, the AI could fail to check for launch on the first two IFs, but still go on and check if it rolls the dices to see if it launches.
 
Waw, nice find for the AI coding.

So it's not hard coded into the game? That's actually very interesting :p

Hard coded as in inside the DLL? Yes. Hardcoded as in inside the .exe file? No.

That has been a development of the last 10-12 (?) years, to "extract" as much logic as possible from the .exe to allow for heavy modding. The more in the DLL, the more modable the product (as long as the dll source is shared).

Why are we not seeing a BetterAI-like mod for civ5 then? IMO, because they failed to deliver at vanilla time in two key aspects: quality of the initial product (the Shafer Civ5) that made many a good part of the best modders run away and back to Civ4 modding, and the delay in releasing the dll source.

Now that BNW (the Beach Civ5) is such a good and much better product than the original, there is hope that some of those master modders will look back and give it a chance, or that a new bunch of people (me included) will find the time and energy to start fiddling around with the enormous potential of the code.

Time will tell.
 
Top Bottom