1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-16 10:19:47 +02:00
vcmi/AI/Nullkiller/Engine/PriorityEvaluator.h

132 lines
4.0 KiB
C++
Raw Normal View History

/*
* PriorityEvaluator.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#if __has_include(<fuzzylite/Headers.h>)
# include <fuzzylite/Headers.h>
#else
# include <fl/Headers.h>
#endif
#include "../Goals/CGoal.h"
2021-05-16 13:55:47 +02:00
#include "../Pathfinding/AIPathfinder.h"
VCMI_LIB_NAMESPACE_BEGIN
VCMI_LIB_NAMESPACE_END
2022-09-26 20:01:07 +02:00
namespace NKAI
{
class BuildingInfo;
2021-05-16 13:55:47 +02:00
class Nullkiller;
2023-02-28 09:07:59 +02:00
struct HitMapInfo;
class RewardEvaluator
{
public:
const Nullkiller * ai;
RewardEvaluator(const Nullkiller * ai) : ai(ai) {}
uint64_t getArmyReward(const CGObjectInstance * target, const CGHeroInstance * hero, const CCreatureSet * army, bool checkGold) const;
2023-05-14 08:17:15 +02:00
uint64_t getArmyGrowth(const CGObjectInstance * target, const CGHeroInstance * hero, const CCreatureSet * army) const;
int getGoldCost(const CGObjectInstance * target, const CGHeroInstance * hero, const CCreatureSet * army) const;
float getEnemyHeroStrategicalValue(const CGHeroInstance * enemy) const;
float getResourceRequirementStrength(int resType) const;
2024-04-20 14:28:42 +02:00
float getResourceRequirementStrength(const TResources & res) const;
float getStrategicalValue(const CGObjectInstance * target, const CGHeroInstance * hero = nullptr) const;
float getConquestValue(const CGObjectInstance* target) const;
float getTotalResourceRequirementStrength(int resType) const;
float evaluateWitchHutSkillScore(const CGObjectInstance * hut, const CGHeroInstance * hero, HeroRole role) const;
float getSkillReward(const CGObjectInstance * target, const CGHeroInstance * hero, HeroRole role) const;
int32_t getGoldReward(const CGObjectInstance * target, const CGHeroInstance * hero) const;
uint64_t getUpgradeArmyReward(const CGTownInstance * town, const BuildingInfo & bi) const;
2023-02-28 09:07:59 +02:00
const HitMapInfo & getEnemyHeroDanger(const int3 & tile, uint8_t turn) const;
2023-06-11 18:21:50 +02:00
uint64_t townArmyGrowth(const CGTownInstance * town) const;
2023-09-24 12:07:42 +02:00
uint64_t getManaRecoveryArmyReward(const CGHeroInstance * hero) const;
};
2021-05-16 13:38:53 +02:00
struct DLL_EXPORT EvaluationContext
{
float movementCost;
std::map<HeroRole, float> movementCostByRole;
int manaCost;
uint64_t danger;
float closestWayRatio;
float armyLossPersentage;
float armyReward;
2023-05-14 08:17:15 +02:00
uint64_t armyGrowth;
2021-05-16 13:38:53 +02:00
int32_t goldReward;
int32_t goldCost;
float skillReward;
float strategicalValue;
float conquestValue;
2021-05-16 13:38:53 +02:00
HeroRole heroRole;
uint8_t turn;
RewardEvaluator evaluator;
float enemyHeroDangerRatio;
Decisionmaking-changes There's 3 new evaluation-contexts that are now taken into account: Whether an action is building, whether an action involves sailing and the newly introduced threat. The value-evaluation of creatures now also takes special resources into account. No longer treating other AIs differently than players when it comes to how afraid we shall be of them. The cost of buildings for decision-making now determines missing resources. Available resources are ignored when it comes to how they impact the cost. But missing-resources will heftily impact the assumed price by calculating their market-value. This shall encourage the AI to rather build what it currently can build instead of saving up for something that it lacking the special resources for. AI is no longer willing to sacrifice more than 25% of their army for any attack except when it has no towns left. Revamped the priority-tiers of AI decision-making. Higest priority is conquering enemy towns and killing enemy heroes. However, the AI will no longer try to do so when the target is more than one turn away and protected by a nearby enemy-hero that could kill the one tasked with dealing with the target. Except when they have no towns left. Then they get desperate and try everything. As a general rule of thumb one could say the AI will prioritize conquest over collecting freebies over investing army to get something that isn't a city. It's a bit more complex than that but this is roughly what can be expected. It will also highly value their own heroes safety during all this.
2024-07-15 18:12:52 +02:00
float threat;
float armyInvolvement;
int defenseValue;
bool isDefend;
TResources buildingCost;
Decisionmaking-changes There's 3 new evaluation-contexts that are now taken into account: Whether an action is building, whether an action involves sailing and the newly introduced threat. The value-evaluation of creatures now also takes special resources into account. No longer treating other AIs differently than players when it comes to how afraid we shall be of them. The cost of buildings for decision-making now determines missing resources. Available resources are ignored when it comes to how they impact the cost. But missing-resources will heftily impact the assumed price by calculating their market-value. This shall encourage the AI to rather build what it currently can build instead of saving up for something that it lacking the special resources for. AI is no longer willing to sacrifice more than 25% of their army for any attack except when it has no towns left. Revamped the priority-tiers of AI decision-making. Higest priority is conquering enemy towns and killing enemy heroes. However, the AI will no longer try to do so when the target is more than one turn away and protected by a nearby enemy-hero that could kill the one tasked with dealing with the target. Except when they have no towns left. Then they get desperate and try everything. As a general rule of thumb one could say the AI will prioritize conquest over collecting freebies over investing army to get something that isn't a city. It's a bit more complex than that but this is roughly what can be expected. It will also highly value their own heroes safety during all this.
2024-07-15 18:12:52 +02:00
bool involvesSailing;
bool isTradeBuilding;
2021-05-16 13:38:53 +02:00
EvaluationContext(const Nullkiller * ai);
void addNonCriticalStrategicalValue(float value);
2021-05-16 13:38:53 +02:00
};
class IEvaluationContextBuilder
{
public:
2022-09-22 10:02:16 +02:00
virtual ~IEvaluationContextBuilder() = default;
2021-05-16 13:38:53 +02:00
virtual void buildEvaluationContext(EvaluationContext & evaluationContext, Goals::TSubgoal goal) const = 0;
};
class Nullkiller;
class PriorityEvaluator
{
public:
PriorityEvaluator(const Nullkiller * ai);
~PriorityEvaluator();
void initVisitTile();
Decisionmaking-changes There's 3 new evaluation-contexts that are now taken into account: Whether an action is building, whether an action involves sailing and the newly introduced threat. The value-evaluation of creatures now also takes special resources into account. No longer treating other AIs differently than players when it comes to how afraid we shall be of them. The cost of buildings for decision-making now determines missing resources. Available resources are ignored when it comes to how they impact the cost. But missing-resources will heftily impact the assumed price by calculating their market-value. This shall encourage the AI to rather build what it currently can build instead of saving up for something that it lacking the special resources for. AI is no longer willing to sacrifice more than 25% of their army for any attack except when it has no towns left. Revamped the priority-tiers of AI decision-making. Higest priority is conquering enemy towns and killing enemy heroes. However, the AI will no longer try to do so when the target is more than one turn away and protected by a nearby enemy-hero that could kill the one tasked with dealing with the target. Except when they have no towns left. Then they get desperate and try everything. As a general rule of thumb one could say the AI will prioritize conquest over collecting freebies over investing army to get something that isn't a city. It's a bit more complex than that but this is roughly what can be expected. It will also highly value their own heroes safety during all this.
2024-07-15 18:12:52 +02:00
float evaluate(Goals::TSubgoal task, int priorityTier = 3);
private:
const Nullkiller * ai;
fl::Engine * engine;
fl::InputVariable * armyLossPersentageVariable;
fl::InputVariable * heroRoleVariable;
fl::InputVariable * mainTurnDistanceVariable;
fl::InputVariable * scoutTurnDistanceVariable;
fl::InputVariable * turnVariable;
fl::InputVariable * goldRewardVariable;
fl::InputVariable * armyRewardVariable;
2023-05-14 08:17:15 +02:00
fl::InputVariable * armyGrowthVariable;
fl::InputVariable * dangerVariable;
fl::InputVariable * skillRewardVariable;
fl::InputVariable * strategicalValueVariable;
fl::InputVariable * rewardTypeVariable;
fl::InputVariable * closestHeroRatioVariable;
2024-04-16 23:10:15 +02:00
fl::InputVariable * goldPressureVariable;
fl::InputVariable * goldCostVariable;
fl::InputVariable * fearVariable;
fl::OutputVariable * value;
2021-05-16 13:38:53 +02:00
std::vector<std::shared_ptr<IEvaluationContextBuilder>> evaluationContextBuilders;
2021-05-16 13:38:53 +02:00
EvaluationContext buildEvaluationContext(Goals::TSubgoal goal) const;
};
2022-09-26 20:01:07 +02:00
}