Browse Source

Weekend-decisions

When attacking non-neutral towns that are far away, the AI now considers whether their attack would arrive in the same week. If it wouldn't, it means there's a high risk that newly bought troops might flip around who is stronger. So they now refrain from sending a hero towards an enemy town that is too far away.
Xilmi 1 year ago
parent
commit
20f7751e16

+ 9 - 0
AI/Nullkiller/Engine/PriorityEvaluator.cpp

@@ -65,6 +65,7 @@ EvaluationContext::EvaluationContext(const Nullkiller* ai)
 	isExchange(false),
 	isArmyUpgrade(false),
 	isHero(false),
+	isEnemy(false),
 	explorePriority(0)
 {
 }
@@ -1040,6 +1041,8 @@ public:
 			evaluationContext.conquestValue += evaluationContext.evaluator.getConquestValue(target);
 			if (target->ID == Obj::HERO)
 				evaluationContext.isHero = true;
+			if (target->getOwner() != PlayerColor::NEUTRAL && ai->cb->getPlayerRelations(ai->playerID, target->getOwner()) == PlayerRelations::ENEMIES)
+				evaluationContext.isEnemy = true;
 			evaluationContext.goldCost += evaluationContext.evaluator.getGoldCost(target, hero, army);
 			evaluationContext.armyInvolvement += army->getArmyCost();
 		}
@@ -1353,6 +1356,10 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task, int priorityTier)
 
 		float maxWillingToLose = ai->cb->getTownsInfo().empty() ? 1 : 0.5 * powerRatio;
 
+		bool arriveNextWeek = false;
+		if (ai->cb->getDate(Date::DAY_OF_WEEK) + evaluationContext.turn > 7)
+			arriveNextWeek = true;
+
 #if NKAI_TRACE_LEVEL >= 2
 		logAi->trace("BEFORE: priorityTier %d, Evaluated %s, loss: %f, turn: %d, turns main: %f, scout: %f, gold: %f, cost: %d, army gain: %f, army growth: %f skill: %f danger: %d, threatTurns: %d, threat: %d, role: %s, strategical value: %f, conquest value: %f cwr: %f, fear: %f, explorePriority: %d isDefend: %d powerRatio: %d",
 			priorityTier,
@@ -1407,6 +1414,8 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task, int priorityTier)
 			{
 				if (evaluationContext.turn > 0 && evaluationContext.isHero)
 					return 0;
+				if (arriveNextWeek && evaluationContext.isEnemy)
+					return 0;
 				if (evaluationContext.conquestValue > 0 || evaluationContext.explorePriority == 1)
 					score = 1000;
 				if (vstd::isAlmostZero(score) || (evaluationContext.enemyHeroDangerRatio > 1 && (evaluationContext.turn > 0 || evaluationContext.isExchange) && !ai->cb->getTownsInfo().empty()))

+ 1 - 0
AI/Nullkiller/Engine/PriorityEvaluator.h

@@ -82,6 +82,7 @@ struct DLL_EXPORT EvaluationContext
 	bool isExchange;
 	bool isArmyUpgrade;
 	bool isHero;
+	bool isEnemy;
 	int explorePriority;
 
 	EvaluationContext(const Nullkiller * ai);