mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-19 21:10:12 +02:00
AI-adjustments
AI no longer rushes towns that don't have a citadel or better when there is a scary enemy hero around. AI will no longer try to maximize defenses by using the strongest possible defender. Instead it will try to use the most appropriate defender. The most appropriate is considered to have roughly 75% power of the threat and the score will be lower but still above zero the bigger the deviation is.
This commit is contained in:
parent
49d73b438b
commit
cf3eee5d8a
@ -1077,6 +1077,8 @@ public:
|
||||
evaluationContext.isHero = true;
|
||||
if (target->getOwner().isValidPlayer() && ai->cb->getPlayerRelations(ai->playerID, target->getOwner()) == PlayerRelations::ENEMIES)
|
||||
evaluationContext.isEnemy = true;
|
||||
if (target->ID == Obj::TOWN)
|
||||
evaluationContext.defenseValue = dynamic_cast<const CGTownInstance*>(target)->fortLevel();
|
||||
evaluationContext.goldCost += evaluationContext.evaluator.getGoldCost(target, hero, army);
|
||||
if(evaluationContext.danger > 0)
|
||||
evaluationContext.skillReward += (float)evaluationContext.danger / (float)hero->getArmyStrength();
|
||||
@ -1465,6 +1467,8 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task, int priorityTier)
|
||||
return 0;
|
||||
if (evaluationContext.movementCost >= 1)
|
||||
return 0;
|
||||
if (evaluationContext.defenseValue < 2 && evaluationContext.enemyHeroDangerRatio > dangerThreshold)
|
||||
return 0;
|
||||
if(evaluationContext.conquestValue > 0)
|
||||
score = evaluationContext.armyInvolvement;
|
||||
if (vstd::isAlmostZero(score) || (evaluationContext.enemyHeroDangerRatio > dangerThreshold && (evaluationContext.turn > 0 || evaluationContext.isExchange) && !ai->cb->getTownsInfo().empty()))
|
||||
@ -1487,13 +1491,30 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task, int priorityTier)
|
||||
if (evaluationContext.isEnemy && evaluationContext.turn > 0)
|
||||
return 0;
|
||||
if (evaluationContext.isDefend && evaluationContext.threatTurns <= evaluationContext.turn)
|
||||
score = evaluationContext.armyInvolvement / (evaluationContext.turn + 1);
|
||||
{
|
||||
const float OPTIMAL_PERCENTAGE = 0.75f; // We want army to be 75% of the threat
|
||||
float optimalStrength = evaluationContext.threat * OPTIMAL_PERCENTAGE;
|
||||
|
||||
// Calculate how far the army is from optimal strength
|
||||
float deviation = std::abs(evaluationContext.armyInvolvement - optimalStrength);
|
||||
|
||||
// Convert deviation to a percentage of the threat to normalize it
|
||||
float deviationPercentage = deviation / evaluationContext.threat;
|
||||
|
||||
// Calculate score: 1.0 is perfect, decreasing as deviation increases
|
||||
score = 1.0f / (1.0f + deviationPercentage);
|
||||
|
||||
// Apply turn penalty to still prefer earlier moves when scores are close
|
||||
score = score / (evaluationContext.turn + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PriorityTier::KILL: //Take towns / kill heroes that are further away
|
||||
//FALL_THROUGH
|
||||
case PriorityTier::FAR_KILL:
|
||||
{
|
||||
if (evaluationContext.defenseValue < 2 && evaluationContext.enemyHeroDangerRatio > dangerThreshold)
|
||||
return 0;
|
||||
if (evaluationContext.turn > 0 && evaluationContext.isHero)
|
||||
return 0;
|
||||
if (arriveNextWeek && evaluationContext.isEnemy)
|
||||
|
Loading…
x
Reference in New Issue
Block a user