mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
AI improvements
AI will no longer skip turns with heroes that are waiting for a delivery that takes more than one turn. Instead they will do something until their delivery is close enough to get it at the same turn. Fixed an issue where a bunch of heroes all tried to do the same tasks: Tasks that involve no fighting will now always be performed by the closest eligible hero while all other heroes look for something else to do.
This commit is contained in:
parent
34b8123fba
commit
c007bbbcd8
@ -1019,12 +1019,20 @@ public:
|
|||||||
evaluationContext.involvesSailing = true;
|
evaluationContext.involvesSailing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float highestCostForSingleHero = 0;
|
||||||
for(auto pair : costsPerHero)
|
for(auto pair : costsPerHero)
|
||||||
{
|
{
|
||||||
auto role = evaluationContext.evaluator.ai->heroManager->getHeroRole(pair.first);
|
auto role = evaluationContext.evaluator.ai->heroManager->getHeroRole(pair.first);
|
||||||
|
|
||||||
evaluationContext.movementCostByRole[role] += pair.second;
|
evaluationContext.movementCostByRole[role] += pair.second;
|
||||||
|
if (pair.second > highestCostForSingleHero)
|
||||||
|
highestCostForSingleHero = pair.second;
|
||||||
}
|
}
|
||||||
|
if (highestCostForSingleHero > 1 && costsPerHero.size() > 1)
|
||||||
|
{
|
||||||
|
//Chains that involve more than 1 hero doing something for more than a turn are too expensive in my book. They often involved heroes doing nothing just standing there waiting to fulfill their part of the chain.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
evaluationContext.movementCost *= costsPerHero.size(); //further deincentivise chaining as it often involves bringing back the army afterwards
|
||||||
|
|
||||||
auto hero = task->hero;
|
auto hero = task->hero;
|
||||||
bool checkGold = evaluationContext.danger == 0;
|
bool checkGold = evaluationContext.danger == 0;
|
||||||
@ -1387,12 +1395,11 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task, int priorityTier)
|
|||||||
if (evaluationContext.turn > 0)
|
if (evaluationContext.turn > 0)
|
||||||
return 0;
|
return 0;
|
||||||
if(evaluationContext.conquestValue > 0)
|
if(evaluationContext.conquestValue > 0)
|
||||||
score = 1000;
|
score = evaluationContext.armyInvolvement;
|
||||||
if (vstd::isAlmostZero(score) || (evaluationContext.enemyHeroDangerRatio > 1 && (evaluationContext.turn > 0 || evaluationContext.isExchange) && !ai->cb->getTownsInfo().empty()))
|
if (vstd::isAlmostZero(score) || (evaluationContext.enemyHeroDangerRatio > 1 && (evaluationContext.turn > 0 || evaluationContext.isExchange) && !ai->cb->getTownsInfo().empty()))
|
||||||
return 0;
|
return 0;
|
||||||
if (maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
if (maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
||||||
return 0;
|
return 0;
|
||||||
score *= evaluationContext.closestWayRatio;
|
|
||||||
if (evaluationContext.movementCost > 0)
|
if (evaluationContext.movementCost > 0)
|
||||||
score /= evaluationContext.movementCost;
|
score /= evaluationContext.movementCost;
|
||||||
break;
|
break;
|
||||||
@ -1403,7 +1410,6 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task, int priorityTier)
|
|||||||
score = evaluationContext.armyInvolvement;
|
score = evaluationContext.armyInvolvement;
|
||||||
if (evaluationContext.isEnemy && maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
if (evaluationContext.isEnemy && maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
||||||
return 0;
|
return 0;
|
||||||
score *= evaluationContext.closestWayRatio;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PriorityTier::KILL: //Take towns / kill heroes that are further away
|
case PriorityTier::KILL: //Take towns / kill heroes that are further away
|
||||||
@ -1413,7 +1419,7 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task, int priorityTier)
|
|||||||
if (arriveNextWeek && evaluationContext.isEnemy)
|
if (arriveNextWeek && evaluationContext.isEnemy)
|
||||||
return 0;
|
return 0;
|
||||||
if (evaluationContext.conquestValue > 0)
|
if (evaluationContext.conquestValue > 0)
|
||||||
score = 1000;
|
score = evaluationContext.armyInvolvement;
|
||||||
if (vstd::isAlmostZero(score) || (evaluationContext.enemyHeroDangerRatio > 1 && (evaluationContext.turn > 0 || evaluationContext.isExchange) && !ai->cb->getTownsInfo().empty()))
|
if (vstd::isAlmostZero(score) || (evaluationContext.enemyHeroDangerRatio > 1 && (evaluationContext.turn > 0 || evaluationContext.isExchange) && !ai->cb->getTownsInfo().empty()))
|
||||||
return 0;
|
return 0;
|
||||||
if (maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
if (maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
||||||
@ -1431,8 +1437,9 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task, int priorityTier)
|
|||||||
return 0;
|
return 0;
|
||||||
if (maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
if (maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (evaluationContext.armyLossPersentage == 0 && evaluationContext.closestWayRatio < 1.0)
|
||||||
|
return 0;
|
||||||
score = 1000;
|
score = 1000;
|
||||||
score *= evaluationContext.closestWayRatio;
|
|
||||||
if (evaluationContext.movementCost > 0)
|
if (evaluationContext.movementCost > 0)
|
||||||
score /= evaluationContext.movementCost;
|
score /= evaluationContext.movementCost;
|
||||||
break;
|
break;
|
||||||
@ -1445,8 +1452,9 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task, int priorityTier)
|
|||||||
return 0;
|
return 0;
|
||||||
if (maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
if (maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (evaluationContext.armyLossPersentage == 0 && evaluationContext.closestWayRatio < 1.0)
|
||||||
|
return 0;
|
||||||
score = 1000;
|
score = 1000;
|
||||||
score *= evaluationContext.closestWayRatio;
|
|
||||||
if (evaluationContext.movementCost > 0)
|
if (evaluationContext.movementCost > 0)
|
||||||
score /= evaluationContext.movementCost;
|
score /= evaluationContext.movementCost;
|
||||||
break;
|
break;
|
||||||
@ -1467,6 +1475,8 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task, int priorityTier)
|
|||||||
return 0;
|
return 0;
|
||||||
if (maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
if (maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (evaluationContext.armyLossPersentage == 0 && evaluationContext.closestWayRatio < 1.0)
|
||||||
|
return 0;
|
||||||
score += evaluationContext.strategicalValue * 1000;
|
score += evaluationContext.strategicalValue * 1000;
|
||||||
score += evaluationContext.goldReward;
|
score += evaluationContext.goldReward;
|
||||||
score += evaluationContext.skillReward * evaluationContext.armyInvolvement * (1 - evaluationContext.armyLossPersentage) * 0.05;
|
score += evaluationContext.skillReward * evaluationContext.armyInvolvement * (1 - evaluationContext.armyLossPersentage) * 0.05;
|
||||||
@ -1477,7 +1487,6 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task, int priorityTier)
|
|||||||
if (score > 0)
|
if (score > 0)
|
||||||
{
|
{
|
||||||
score = 1000;
|
score = 1000;
|
||||||
score *= evaluationContext.closestWayRatio;
|
|
||||||
if (evaluationContext.movementCost > 0)
|
if (evaluationContext.movementCost > 0)
|
||||||
score /= evaluationContext.movementCost;
|
score /= evaluationContext.movementCost;
|
||||||
}
|
}
|
||||||
@ -1491,8 +1500,9 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task, int priorityTier)
|
|||||||
return 0;
|
return 0;
|
||||||
if (maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
if (maxWillingToLose - evaluationContext.armyLossPersentage < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (evaluationContext.closestWayRatio < 1.0)
|
||||||
|
return 0;
|
||||||
score = 1000;
|
score = 1000;
|
||||||
score *= evaluationContext.closestWayRatio;
|
|
||||||
if (evaluationContext.movementCost > 0)
|
if (evaluationContext.movementCost > 0)
|
||||||
score /= evaluationContext.movementCost;
|
score /= evaluationContext.movementCost;
|
||||||
break;
|
break;
|
||||||
@ -1502,8 +1512,7 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task, int priorityTier)
|
|||||||
if (evaluationContext.enemyHeroDangerRatio > 1 && evaluationContext.isExchange)
|
if (evaluationContext.enemyHeroDangerRatio > 1 && evaluationContext.isExchange)
|
||||||
return 0;
|
return 0;
|
||||||
if (evaluationContext.isDefend || evaluationContext.isArmyUpgrade)
|
if (evaluationContext.isDefend || evaluationContext.isArmyUpgrade)
|
||||||
score = 1000;
|
score = evaluationContext.armyInvolvement;
|
||||||
score *= evaluationContext.closestWayRatio;
|
|
||||||
score /= (evaluationContext.turn + 1);
|
score /= (evaluationContext.turn + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user