mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
Nullkiller: initial decomposition
This commit is contained in:
committed by
Andrii Danylchenko
parent
223a52b3d1
commit
8f8c5ca255
@@ -36,6 +36,23 @@ class CGTownInstance;
|
||||
extern boost::thread_specific_ptr<CCallback> cb;
|
||||
extern boost::thread_specific_ptr<VCAI> ai;
|
||||
|
||||
EvaluationContext::EvaluationContext()
|
||||
: movementCost(0.0),
|
||||
manaCost(0),
|
||||
danger(0),
|
||||
closestWayRatio(1),
|
||||
movementCostByRole(),
|
||||
skillReward(0),
|
||||
goldReward(0),
|
||||
goldCost(0),
|
||||
armyReward(0),
|
||||
armyLossPersentage(0),
|
||||
heroRole(HeroRole::SCOUT),
|
||||
turn(0),
|
||||
strategicalValue(0)
|
||||
{
|
||||
}
|
||||
|
||||
PriorityEvaluator::~PriorityEvaluator()
|
||||
{
|
||||
delete engine;
|
||||
@@ -430,46 +447,59 @@ int32_t getGoldReward(const CGObjectInstance * target, const CGHeroInstance * he
|
||||
class ExecuteHeroChainEvaluationContextBuilder : public IEvaluationContextBuilder
|
||||
{
|
||||
public:
|
||||
virtual Goals::EvaluationContext buildEvaluationContext(Goals::TSubgoal task) const override
|
||||
virtual void buildEvaluationContext(EvaluationContext & evaluationContext, Goals::TSubgoal task) const override
|
||||
{
|
||||
if(task->goalType != Goals::EXECUTE_HERO_CHAIN)
|
||||
return;
|
||||
|
||||
Goals::ExecuteHeroChain & chain = dynamic_cast<Goals::ExecuteHeroChain &>(*task);
|
||||
auto evaluationContext = task->evaluationContext;
|
||||
const AIPath & path = chain.getPath();
|
||||
|
||||
vstd::amax(evaluationContext.danger, path.getTotalDanger());
|
||||
evaluationContext.movementCost += path.movementCost();
|
||||
evaluationContext.closestWayRatio = chain.closestWayRatio;
|
||||
|
||||
for(auto & node : path.nodes)
|
||||
{
|
||||
auto role = ai->ah->getHeroRole(node.targetHero);
|
||||
|
||||
evaluationContext.movementCostByRole[role] += node.cost;
|
||||
}
|
||||
|
||||
auto heroPtr = task->hero;
|
||||
const CGObjectInstance * target = cb->getObj((ObjectInstanceID)task->objid, false);
|
||||
auto day = cb->getDate(Date::DAY);
|
||||
auto hero = heroPtr.get();
|
||||
bool checkGold = evaluationContext.danger == 0;
|
||||
auto army = chain.getPath().heroArmy;
|
||||
auto army = path.heroArmy;
|
||||
|
||||
evaluationContext.armyLossPersentage = task->evaluationContext.armyLoss / (double)task->evaluationContext.heroStrength;
|
||||
evaluationContext.heroRole = ai->ah->getHeroRole(heroPtr);
|
||||
evaluationContext.goldReward = getGoldReward(target, hero);
|
||||
evaluationContext.armyReward = getArmyReward(target, hero, army, checkGold);
|
||||
evaluationContext.skillReward = getSkillReward(target, hero, evaluationContext.heroRole);
|
||||
vstd::amax(evaluationContext.armyLossPersentage, path.getTotalArmyLoss() / (double)path.getHeroStrength());
|
||||
vstd::amax(evaluationContext.heroRole, ai->ah->getHeroRole(heroPtr));
|
||||
evaluationContext.goldReward += getGoldReward(target, hero);
|
||||
evaluationContext.armyReward += getArmyReward(target, hero, army, checkGold);
|
||||
evaluationContext.skillReward += getSkillReward(target, hero, evaluationContext.heroRole);
|
||||
evaluationContext.strategicalValue += getStrategicalValue(target);
|
||||
evaluationContext.goldCost = getGoldCost(target, hero, army);
|
||||
evaluationContext.turn = chain.getPath().turn();
|
||||
|
||||
return evaluationContext;
|
||||
evaluationContext.goldCost += getGoldCost(target, hero, army);
|
||||
vstd::amax(evaluationContext.turn, path.turn());
|
||||
}
|
||||
};
|
||||
|
||||
class BuildThisEvaluationContextBuilder : public IEvaluationContextBuilder
|
||||
{
|
||||
public:
|
||||
virtual Goals::EvaluationContext buildEvaluationContext(Goals::TSubgoal task) const override
|
||||
virtual void buildEvaluationContext(EvaluationContext & evaluationContext, Goals::TSubgoal task) const override
|
||||
{
|
||||
Goals::EvaluationContext evaluationContext;
|
||||
if(task->goalType != Goals::BUILD_STRUCTURE)
|
||||
return;
|
||||
|
||||
Goals::BuildThis & buildThis = dynamic_cast<Goals::BuildThis &>(*task);
|
||||
auto & bi = buildThis.buildingInfo;
|
||||
|
||||
evaluationContext.goldReward = 7 * bi.dailyIncome[Res::GOLD] / 2; // 7 day income but half we already have
|
||||
evaluationContext.goldReward += 7 * bi.dailyIncome[Res::GOLD] / 2; // 7 day income but half we already have
|
||||
evaluationContext.heroRole = HeroRole::MAIN;
|
||||
evaluationContext.movementCostByRole[evaluationContext.heroRole] = bi.prerequisitesCount;
|
||||
evaluationContext.armyReward = 0;
|
||||
evaluationContext.strategicalValue = buildThis.townInfo.armyScore / 50000.0;
|
||||
evaluationContext.goldCost = bi.buildCostWithPrerequisits[Res::GOLD];
|
||||
evaluationContext.movementCostByRole[evaluationContext.heroRole] += bi.prerequisitesCount;
|
||||
evaluationContext.strategicalValue += buildThis.townInfo.armyScore / 50000.0;
|
||||
evaluationContext.goldCost += bi.buildCostWithPrerequisits[Res::GOLD];
|
||||
|
||||
if(bi.creatureID != CreatureID::NONE)
|
||||
{
|
||||
@@ -477,38 +507,56 @@ public:
|
||||
|
||||
if(bi.baseCreatureID == bi.creatureID)
|
||||
{
|
||||
evaluationContext.armyReward = ai->ah->evaluateStackPower(bi.creatureID.toCreature(), bi.creatureGrows);
|
||||
evaluationContext.armyReward += ai->ah->evaluateStackPower(bi.creatureID.toCreature(), bi.creatureGrows);
|
||||
}
|
||||
|
||||
auto creaturesToUpgrade = ai->ah->getTotalCreaturesAvailable(bi.baseCreatureID);
|
||||
auto upgradedPower = ai->ah->evaluateStackPower(bi.creatureID.toCreature(), creaturesToUpgrade.count);
|
||||
else
|
||||
{
|
||||
auto creaturesToUpgrade = ai->ah->getTotalCreaturesAvailable(bi.baseCreatureID);
|
||||
auto upgradedPower = ai->ah->evaluateStackPower(bi.creatureID.toCreature(), creaturesToUpgrade.count);
|
||||
|
||||
evaluationContext.armyReward = upgradedPower - creaturesToUpgrade.power;
|
||||
evaluationContext.armyReward += upgradedPower - creaturesToUpgrade.power;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
evaluationContext.strategicalValue = ai->nullkiller->buildAnalyzer->getGoldPreasure() * evaluationContext.goldReward / 2200.0f;
|
||||
evaluationContext.strategicalValue += ai->nullkiller->buildAnalyzer->getGoldPreasure() * evaluationContext.goldReward / 2200.0f;
|
||||
}
|
||||
|
||||
return evaluationContext;
|
||||
}
|
||||
};
|
||||
|
||||
PriorityEvaluator::PriorityEvaluator()
|
||||
{
|
||||
initVisitTile();
|
||||
evaluationContextBuilders[Goals::EXECUTE_HERO_CHAIN] = std::make_shared<ExecuteHeroChainEvaluationContextBuilder>();
|
||||
evaluationContextBuilders[Goals::BUILD_STRUCTURE] = std::make_shared<BuildThisEvaluationContextBuilder>();
|
||||
evaluationContextBuilders.push_back(std::make_shared<ExecuteHeroChainEvaluationContextBuilder>());
|
||||
evaluationContextBuilders.push_back(std::make_shared<BuildThisEvaluationContextBuilder>());
|
||||
}
|
||||
|
||||
Goals::EvaluationContext PriorityEvaluator::buildEvaluationContext(Goals::TSubgoal goal) const
|
||||
EvaluationContext PriorityEvaluator::buildEvaluationContext(Goals::TSubgoal goal) const
|
||||
{
|
||||
auto builder = evaluationContextBuilders.find(goal->goalType);
|
||||
Goals::TGoalVec parts;
|
||||
EvaluationContext context;
|
||||
|
||||
if(builder == evaluationContextBuilders.end())
|
||||
return goal->evaluationContext;
|
||||
if(goal->goalType == Goals::COMPOSITION)
|
||||
{
|
||||
parts = goal->decompose();
|
||||
}
|
||||
else
|
||||
{
|
||||
parts.push_back(goal);
|
||||
}
|
||||
|
||||
return builder->second->buildEvaluationContext(goal);
|
||||
for(auto goal : parts)
|
||||
{
|
||||
context.strategicalValue += goal->strategicalValue;
|
||||
context.goldCost += goal->goldCost;
|
||||
|
||||
for(auto builder : evaluationContextBuilders)
|
||||
{
|
||||
builder->buildEvaluationContext(context, goal);
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/// distance
|
||||
|
||||
Reference in New Issue
Block a user