1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-26 03:52:01 +02:00

Nullkiller: armed heros prefer armed targets

This commit is contained in:
Andrii Danylchenko 2021-05-15 21:57:40 +03:00 committed by Andrii Danylchenko
parent 4bf653f596
commit 3744125270
2 changed files with 28 additions and 14 deletions

View File

@ -48,11 +48,13 @@ void PriorityEvaluator::initVisitTile()
{ {
try try
{ {
armyLossPersentageVariable = new fl::InputVariable("armyLoss"); //hero must be strong enough to defeat guards armyLossPersentageVariable = new fl::InputVariable("armyLoss");
heroStrengthVariable = new fl::InputVariable("heroStrength"); //we want to use weakest possible hero armyStrengthVariable = new fl::InputVariable("armyStrength");
turnDistanceVariable = new fl::InputVariable("turnDistance"); //we want to use hero who is near dangerVariable = new fl::InputVariable("danger");
goldRewardVariable = new fl::InputVariable("goldReward"); //indicate AI that content of the file is important or it is probably bad turnDistanceVariable = new fl::InputVariable("turnDistance");
armyRewardVariable = new fl::InputVariable("armyReward"); //indicate AI that content of the file is important or it is probably bad goldRewardVariable = new fl::InputVariable("goldReward");
armyRewardVariable = new fl::InputVariable("armyReward");
value = new fl::OutputVariable("Value"); value = new fl::OutputVariable("Value");
value->setMinimum(0); value->setMinimum(0);
value->setMaximum(1); value->setMaximum(1);
@ -67,10 +69,11 @@ void PriorityEvaluator::initVisitTile()
std::vector<fl::InputVariable *> helper = { std::vector<fl::InputVariable *> helper = {
armyLossPersentageVariable, armyLossPersentageVariable,
heroStrengthVariable, armyStrengthVariable,
turnDistanceVariable, turnDistanceVariable,
goldRewardVariable, goldRewardVariable,
armyRewardVariable }; armyRewardVariable,
dangerVariable };
for(auto val : helper) for(auto val : helper)
{ {
@ -83,10 +86,10 @@ void PriorityEvaluator::initVisitTile()
armyLossPersentageVariable->setRange(0, 1); armyLossPersentageVariable->setRange(0, 1);
//strength compared to our main hero //strength compared to our main hero
heroStrengthVariable->addTerm(new fl::Ramp("LOW", 0.2, 0)); armyStrengthVariable->addTerm(new fl::Ramp("LOW", 0.2, 0));
heroStrengthVariable->addTerm(new fl::Triangle("MEDIUM", 0.2, 0.8)); armyStrengthVariable->addTerm(new fl::Triangle("MEDIUM", 0.2, 0.8));
heroStrengthVariable->addTerm(new fl::Ramp("HIGH", 0.5, 1)); armyStrengthVariable->addTerm(new fl::Ramp("HIGH", 0.5, 1));
heroStrengthVariable->setRange(0.0, 1.0); armyStrengthVariable->setRange(0.0, 1.0);
turnDistanceVariable->addTerm(new fl::Ramp("SMALL", 1.000, 0.000)); turnDistanceVariable->addTerm(new fl::Ramp("SMALL", 1.000, 0.000));
turnDistanceVariable->addTerm(new fl::Triangle("MEDIUM", 0.000, 1.000, 2.000)); turnDistanceVariable->addTerm(new fl::Triangle("MEDIUM", 0.000, 1.000, 2.000));
@ -103,6 +106,9 @@ void PriorityEvaluator::initVisitTile()
armyRewardVariable->addTerm(new fl::Ramp("HIGH", 0.400, 1.000)); armyRewardVariable->addTerm(new fl::Ramp("HIGH", 0.400, 1.000));
armyRewardVariable->setRange(0.0, 1.0); armyRewardVariable->setRange(0.0, 1.0);
dangerVariable->addTerm(new fl::Ramp("NONE", 50, 0));
dangerVariable->addTerm(new fl::Ramp("HIGH", 50, 10000));
value->addTerm(new fl::Ramp("LOWEST", 0.150, 0.000)); value->addTerm(new fl::Ramp("LOWEST", 0.150, 0.000));
value->addTerm(new fl::Triangle("LOW", 0.100, 0.100, 0.250, 0.500)); value->addTerm(new fl::Triangle("LOW", 0.100, 0.100, 0.250, 0.500));
value->addTerm(new fl::Triangle("BITLOW", 0.200, 0.200, 0.350, 0.250)); value->addTerm(new fl::Triangle("BITLOW", 0.200, 0.200, 0.350, 0.250));
@ -147,6 +153,8 @@ void PriorityEvaluator::initVisitTile()
addRule("if armyLoss is HIGH then Value is LOWEST"); addRule("if armyLoss is HIGH then Value is LOWEST");
addRule("if armyLoss is LOW then Value is MEDIUM"); addRule("if armyLoss is LOW then Value is MEDIUM");
addRule("if armyReward is LOW and turnDistance is LONG then Value is LOWEST"); addRule("if armyReward is LOW and turnDistance is LONG then Value is LOWEST");
addRule("if danger is NONE and armyStrength is HIGH and armyReward is LOW then Value is LOW");
addRule("if danger is NONE and armyStrength is HIGH and armyReward is MEDIUM then Value is BITLOW");
} }
catch(fl::Exception & fe) catch(fl::Exception & fe)
{ {
@ -307,15 +315,18 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task)
double armyLossPersentage = task->evaluationContext.armyLoss / (double)armyTotal; double armyLossPersentage = task->evaluationContext.armyLoss / (double)armyTotal;
int32_t goldReward = getGoldReward(target, hero); int32_t goldReward = getGoldReward(target, hero);
uint64_t armyReward = getArmyReward(target, hero); uint64_t armyReward = getArmyReward(target, hero);
uint64_t danger = task->evaluationContext.danger;
float armyStrength = (fl::scalar)hero->getArmyStrength() / ai->primaryHero()->getArmyStrength();
double result = 0; double result = 0;
try try
{ {
armyLossPersentageVariable->setValue(armyLossPersentage); armyLossPersentageVariable->setValue(armyLossPersentage);
heroStrengthVariable->setValue((fl::scalar)hero->getTotalStrength() / ai->primaryHero()->getTotalStrength()); armyStrengthVariable->setValue(armyStrength);
turnDistanceVariable->setValue(task->evaluationContext.movementCost); turnDistanceVariable->setValue(task->evaluationContext.movementCost);
goldRewardVariable->setValue(goldReward); goldRewardVariable->setValue(goldReward);
armyRewardVariable->setValue(armyReward / 10000.0); armyRewardVariable->setValue(armyReward / 10000.0);
dangerVariable->setValue(danger);
engine.process(); engine.process();
//engine.process(VISIT_TILE); //TODO: Process only Visit_Tile //engine.process(VISIT_TILE); //TODO: Process only Visit_Tile
@ -328,12 +339,14 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task)
assert(result >= 0); assert(result >= 0);
#ifdef VCMI_TRACE_PATHFINDER #ifdef VCMI_TRACE_PATHFINDER
logAi->trace("Evaluated %s, loss: %f, turns: %f, gold: %d, army gain: %d, result %f", logAi->trace("Evaluated %s, loss: %f, turns: %f, gold: %d, army gain: %d, danger: %d, army strength: %f%%, result %f",
task->name(), task->name(),
armyLossPersentage, armyLossPersentage,
task->evaluationContext.movementCost, task->evaluationContext.movementCost,
goldReward, goldReward,
armyReward, armyReward,
danger,
(int)(armyStrength * 100),
result); result);
#endif #endif

View File

@ -28,9 +28,10 @@ public:
private: private:
fl::InputVariable * armyLossPersentageVariable; fl::InputVariable * armyLossPersentageVariable;
fl::InputVariable * heroStrengthVariable; fl::InputVariable * armyStrengthVariable;
fl::InputVariable * turnDistanceVariable; fl::InputVariable * turnDistanceVariable;
fl::InputVariable * goldRewardVariable; fl::InputVariable * goldRewardVariable;
fl::InputVariable * armyRewardVariable; fl::InputVariable * armyRewardVariable;
fl::InputVariable * dangerVariable;
fl::OutputVariable * value; fl::OutputVariable * value;
}; };