Siege unit valuation

Fimbulvetr

Emperor
Joined
Nov 5, 2009
Messages
1,267
Location
Austria
Even at warning level 4 I get nothing when compiling this part of code I wrote, which simply tries to improve valuation of siege units for UNITAI_ATTACK_CITY, taking into account how many siege units the player already has and how big the rest of the offensive army is.. so what am I doing wrong here? It's crashing so often I have to assume it crashes always when a siege unit is already in an AI's army and it's thinking about building another one. (not really sure though)


CvPlayerAI.cpp (based on ideas from Better BTS AI)
Spoiler :
Code:
	case UNITAI_ATTACK_CITY:
		[COLOR="Green"]// Effect army composition to have more collateral/bombard units[/COLOR]
		iFastMoverMultiplier = AI_isDoStrategy(AI_STRATEGY_FASTMOVERS) ? 4 : 1;
		
		iTempValue = ((iCombatValue * iCombatValue) / 75) + (iCombatValue / 2);
		iValue += iTempValue;
		if (GC.getUnitInfo(eUnit).isNoDefensiveBonus())
		{
			iValue -= iTempValue / 2;
		}
		if (GC.getUnitInfo(eUnit).getDropRange() > 0)
		{
			iValue -= iTempValue / 2;
		}
		if (GC.getUnitInfo(eUnit).isFirstStrikeImmune())
		{
			iValue += (iTempValue * 8) / 100;
		}		
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getCityAttackModifier()) / 75);
[COLOR="Green"]/* Collateral Damage valuation moved to bombard part
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getCollateralDamage()) / 400);
*/[/COLOR]
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getMoves() * iFastMoverMultiplier) / 4);
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getWithdrawalProbability()) / 100);
[COLOR="Green"]/*
		if (!AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ))
		{
*/[/COLOR]
			if (GC.getUnitInfo(eUnit).getBombardRate() > 0 || GC.getUnitInfo(eUnit).getCollateralDamageMaxUnits() > 0)
			{
[COLOR="Green"]				/* original code
				int iBombardValue = GC.getUnitInfo(eUnit).getBombardRate() * 4;
				*/[/COLOR]
				int iBombardValue = GC.getUnitInfo(eUnit).getBombardRate() * (GC.getUnitInfo(eUnit).isIgnoreBuildingDefense() ? 3 : 2);
				[COLOR="Green"]// Army composition needs to scale with army size, bombard unit potency[/COLOR]


				
				[COLOR="Green"]//modified AI_calculateTotalBombard(DOMAIN_LAND) code[/COLOR]
				int iI;
				int iTotalBombard = 0;
				int iSiegeUnits = 0;
				int iSiegeImmune = 0;
				int iTotalSiegeMaxUnits = 0;
				
				for (iI = 0; iI < GC.getNumUnitClassInfos(); iI++)
				{
					UnitTypes eLoopUnit = ((UnitTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(iI)));
					if (eLoopUnit != NO_UNIT)
					{
						if (GC.getUnitInfo(eLoopUnit).getDomainType() == DOMAIN_LAND)
						{
							int iBombardRate = GC.getUnitInfo(eLoopUnit).getBombardRate();
							
							if (iBombardRate > 0)
							{
								iTotalBombard += (iBombardRate * getUnitClassCount((UnitClassTypes)iI) * (GC.getUnitInfo(eUnit).isIgnoreBuildingDefense() ? 3 : 2)) / 2;
							}
							
							int iBombRate = GC.getUnitInfo(eLoopUnit).getBombRate();
							if (iBombRate > 0)
							{
								iTotalBombard += iBombRate * getUnitClassCount((UnitClassTypes)iI);
							}
							
							
							if (GC.getUnitInfo(eLoopUnit).getCollateralDamageMaxUnits() != 0 && GC.getUnitInfo(eLoopUnit).getCollateralDamage() != 0)
							{
								iTotalSiegeMaxUnits += GC.getUnitInfo(eLoopUnit).getCollateralDamageMaxUnits() * getUnitClassCount((UnitClassTypes)iI);
								iSiegeUnits += getUnitClassCount((UnitClassTypes)iI);
							}
							else if (GC.getUnitInfo(eLoopUnit).getUnitCombatCollateralImmune(GC.getUnitInfo(eUnit).getUnitCombatType()))
							{
								iSiegeImmune+= getUnitClassCount((UnitClassTypes)iI);
							}
						}
					}
				}

				int iNumOffensiveUnits = AI_totalUnitAIs(UNITAI_ATTACK_CITY) + AI_totalUnitAIs(UNITAI_ATTACK) + AI_totalUnitAIs(UNITAI_COUNTER)/2;
				int iNumDefensiveUnits = AI_totalUnitAIs(UNITAI_CITY_DEFENSE) + AI_totalUnitAIs(UNITAI_RESERVE) + AI_totalUnitAIs(UNITAI_CITY_COUNTER)/2 + AI_totalUnitAIs(UNITAI_COLLATERAL)/2;
				iSiegeUnits += (iSiegeImmune*iNumOffensiveUnits)/(iNumOffensiveUnits+iNumDefensiveUnits);

				int iMAX_HIT_POINTS = GC.getDefineINT("MAX_HIT_POINTS");

				int iCollateralDamageMaxUnitsWeight = (100 * (iNumOffensiveUnits - iSiegeUnits)) / std::max(1,iTotalSiegeMaxUnits);
				iCollateralDamageMaxUnitsWeight = std::min(100, iCollateralDamageMaxUnitsWeight);
				[COLOR="Green"]//to decrease value further for units with low damage limits:[/COLOR]
				int iCollateralDamageLimitWeight = 100*iMAX_HIT_POINTS - std::max(0, ((iMAX_HIT_POINTS - GC.getUnitInfo(eUnit).getCollateralDamageLimit()) * (100 -  iCollateralDamageMaxUnitsWeight)));
				iCollateralDamageLimitWeight /= iMAX_HIT_POINTS;
				int iCollateralValue = iCombatValue * GC.getUnitInfo(eUnit).getCollateralDamage() * GC.getDefineINT("COLLATERAL_COMBAT_DAMAGE");
				iCollateralValue /= 100;
				iCollateralValue *= std::max(100, (GC.getUnitInfo(eUnit).getCollateralDamageMaxUnits() * iCollateralDamageMaxUnitsWeight * iCollateralDamageMaxUnitsWeight) / 100);
				iCollateralValue /= 100;
				iCollateralValue *= iCollateralDamageLimitWeight;
				iCollateralValue /= 100;
				iCollateralValue /= iMAX_HIT_POINTS;
				iValue += iCollateralValue;
				
				[COLOR="Green"]//int iTotalBombardValue = 4 * iTotalBombard;[/COLOR]
				int iNumBombardUnits = 2 * iTotalBombard / iBombardValue;
				int iAIDesiredBombardFraction = std::max( 5, /*default: 10*/ GC.getDefineINT("BBAI_BOMBARD_ATTACK_STACK_FRACTION"));
				int iActualBombardFraction = (100*iNumBombardUnits)/std::max(1, iNumOffensiveUnits);

				int iTempBombardValue = 0;
				if (iTotalBombard < 200) //still less than 200 bombard points
				{
					iTempBombardValue = iBombardValue * (500 - 2*iTotalBombard);
					iTempBombardValue /= 100;
					[COLOR="Green"]//iTempBombardValue is at most (5 * iBombardValue)[/COLOR]
				}
				if (iActualBombardFraction < iAIDesiredBombardFraction)
				{
					iBombardValue *= iAIDesiredBombardFraction + 3 * (iAIDesiredBombardFraction - iActualBombardFraction);
					iBombardValue /= iAIDesiredBombardFraction;
					[COLOR="Green"]//new iBombardValue is at most (4 * old iBombardValue)[/COLOR]
				}
				else
				{
					iBombardValue *= iAIDesiredBombardFraction;
					iBombardValue /= range(iActualBombardFraction,1,99);
				}

				if (iTempBombardValue > iBombardValue)
				{
					iBombardValue = iTempBombardValue;
				}
				
				if (!AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ))
				{
					iValue += iBombardValue;
				}
			}
[COLOR="Green"]/*
		}
*/[/COLOR]
		break;

edit: nvm, it suddenly works after a few changes that as far as I can see shouldn't really change anything. mysterious ..

Spoiler :
Code:
	case UNITAI_ATTACK_CITY:
		[COLOR="Green"]// Effect army composition to have more collateral/bombard units[/COLOR]
		iFastMoverMultiplier = AI_isDoStrategy(AI_STRATEGY_FASTMOVERS) ? 4 : 1;
		
		iTempValue = ((iCombatValue * iCombatValue) / 75) + (iCombatValue / 2);
		iValue += iTempValue;
		if (GC.getUnitInfo(eUnit).isNoDefensiveBonus())
		{
			iValue -= iTempValue / 2;
		}
		if (GC.getUnitInfo(eUnit).getDropRange() > 0)
		{
			iValue -= iTempValue / 2;
		}
		if (GC.getUnitInfo(eUnit).isFirstStrikeImmune())
		{
			iValue += (iTempValue * 8) / 100;
		}		
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getCityAttackModifier()) / 75);
[COLOR="Green"]/* Collateral Damage valuation moved to bombard part
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getCollateralDamage()) / 400);
*/[/COLOR]
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getMoves() * iFastMoverMultiplier) / 4);
		iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getWithdrawalProbability()) / 100);
[COLOR="Green"]/*
		if (!AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ))
		{
*/[/COLOR]
			if (GC.getUnitInfo(eUnit).getBombardRate() > 0 || (GC.getUnitInfo(eUnit).getCollateralDamageMaxUnits() > 0 && GC.getUnitInfo(eUnit).getCollateralDamage() > 0))
			{
				[COLOR="Green"]// Army composition needs to scale with army size, bombard unit potency[/COLOR]

				[COLOR="Green"]//modified AI_calculateTotalBombard(DOMAIN_LAND) code[/COLOR]
				int iII;
				int iTotalBombard = 0;
				int iSiegeUnits = 0;
				int iSiegeImmune = 0;
				int iTotalSiegeMaxUnits = 0;
				
				for (iII = 0; iII < GC.getNumUnitClassInfos(); iII++)
				{
					UnitTypes eLoopUnit = ((UnitTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(iII)));
					if (eLoopUnit != NO_UNIT)
					{
						if (GC.getUnitInfo(eLoopUnit).getDomainType() == DOMAIN_LAND)
						{
							int iClassCount = getUnitClassCount((UnitClassTypes)iII);
							int iBombardRate = GC.getUnitInfo(eLoopUnit).getBombardRate();
							
							if (iBombardRate > 0)
							{
								iTotalBombard += ((iBombardRate * iClassCount * ((GC.getUnitInfo(eLoopUnit).isIgnoreBuildingDefense()) ? 3 : 2)) / 2);
							}
							
							int iBombRate = GC.getUnitInfo(eLoopUnit).getBombRate();
							if (iBombRate > 0)
							{
								iTotalBombard += iBombRate * iClassCount;
							}
							
							int iCollateralDamageMaxUnits = GC.getUnitInfo(eLoopUnit).getCollateralDamageMaxUnits();
							if (iCollateralDamageMaxUnits > 0 && GC.getUnitInfo(eLoopUnit).getCollateralDamage() > 0)
							{
								iTotalSiegeMaxUnits += iCollateralDamageMaxUnits * iClassCount;
								iSiegeUnits += iClassCount;
							}
							else if (GC.getUnitInfo(eLoopUnit).getUnitCombatCollateralImmune((UnitCombatTypes)GC.getUnitInfo(eUnit).getUnitCombatType()))
							{
								iSiegeImmune+= iClassCount;
							}
						}
					}
				}

				int iNumOffensiveUnits = AI_totalUnitAIs(UNITAI_ATTACK_CITY) + AI_totalUnitAIs(UNITAI_ATTACK) + AI_totalUnitAIs(UNITAI_COUNTER)/2;
				int iNumDefensiveUnits = AI_totalUnitAIs(UNITAI_CITY_DEFENSE) + AI_totalUnitAIs(UNITAI_RESERVE) + AI_totalUnitAIs(UNITAI_CITY_COUNTER)/2 + AI_totalUnitAIs(UNITAI_COLLATERAL)/2;
				iSiegeUnits += (iSiegeImmune*iNumOffensiveUnits)/(iNumOffensiveUnits+iNumDefensiveUnits);

				int iMAX_HIT_POINTS = GC.getDefineINT("MAX_HIT_POINTS");

				int iCollateralDamageMaxUnitsWeight = (100 * (iNumOffensiveUnits - iSiegeUnits)) / std::max(1,iTotalSiegeMaxUnits);
				iCollateralDamageMaxUnitsWeight = std::min(100, iCollateralDamageMaxUnitsWeight);
				[COLOR="Green"]//to decrease value further for units with low damage limits:[/COLOR]
				int iCollateralDamageLimitWeight = 100*iMAX_HIT_POINTS - std::max(0, ((iMAX_HIT_POINTS - GC.getUnitInfo(eUnit).getCollateralDamageLimit()) * (100 -  iCollateralDamageMaxUnitsWeight)));
				iCollateralDamageLimitWeight /= iMAX_HIT_POINTS;

				int iCollateralValue = iCombatValue * GC.getUnitInfo(eUnit).getCollateralDamage() * GC.getDefineINT("COLLATERAL_COMBAT_DAMAGE");
				iCollateralValue /= 100;
				iCollateralValue *= std::max(100, ((GC.getUnitInfo(eUnit).getCollateralDamageMaxUnits() * iCollateralDamageMaxUnitsWeight * iCollateralDamageMaxUnitsWeight) / 100));
				iCollateralValue /= 100;
				iCollateralValue *= iCollateralDamageLimitWeight;
				iCollateralValue /= 100;
				iCollateralValue /= iMAX_HIT_POINTS;
				iValue += iCollateralValue;
				
				if (!AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ) && GC.getUnitInfo(eUnit).getBombardRate() > 0)
				{
[COLOR="Green"]					/* original code
					int iBombardValue = GC.getUnitInfo(eUnit).getBombardRate() * 4;
					*/[/COLOR]
					int iBombardValue = GC.getUnitInfo(eUnit).getBombardRate() * ((GC.getUnitInfo(eUnit).isIgnoreBuildingDefense()) ? 3 : 2);
					[COLOR="Green"]//int iTotalBombardValue = 4 * iTotalBombard;[/COLOR]
					[COLOR="Green"]//int iNumBombardUnits = 2 * iTotalBombard / iBombardValue;[/COLOR]
					int iAIDesiredBombardFraction = std::max( 5, GC.getDefineINT("BBAI_BOMBARD_ATTACK_STACK_FRACTION")); /*default: 10*/
					int iActualBombardFraction = (100 * 2 * iTotalBombard)/(iBombardValue * std::max(1, iNumOffensiveUnits));
					iActualBombardFraction = std::min(100, iActualBombardFraction);


					int iTempBombardValue = 0;
					if (iTotalBombard < 200) //still less than 200 bombard points
					{
						iTempBombardValue = (iBombardValue * (700 - 3*iTotalBombard));
						iTempBombardValue /= 100;
						[COLOR="Green"]//iTempBombardValue is at most (7 * iBombardValue)[/COLOR]
					}
					if (iActualBombardFraction < iAIDesiredBombardFraction)
					{
						iBombardValue *= (iAIDesiredBombardFraction + 4 * (iAIDesiredBombardFraction - iActualBombardFraction));
						iBombardValue /= iAIDesiredBombardFraction;
						[COLOR="Green"]//new iBombardValue is at most (5 * old iBombardValue)[/COLOR]
					}
					else
					{
						iBombardValue *= iAIDesiredBombardFraction;
						iBombardValue /= std::max(1, iActualBombardFraction);
					}

					if (iTempBombardValue > iBombardValue)
					{
						iBombardValue = iTempBombardValue;
					}

					iValue += iBombardValue;
				}
			}
[COLOR="Green"]/*
		}
*/[/COLOR]
		break;
 
Top Bottom