mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Fuzzy rework
This commit is contained in:
parent
38a98387e4
commit
b1ca663eb6
@ -49,7 +49,8 @@ EvaluationContext::EvaluationContext(const Nullkiller * ai)
|
||||
turn(0),
|
||||
strategicalValue(0),
|
||||
evaluator(ai),
|
||||
enemyHeroDangerRatio(0)
|
||||
enemyHeroDangerRatio(0),
|
||||
armyGrowth(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -64,6 +65,7 @@ void PriorityEvaluator::initVisitTile()
|
||||
std::string str = std::string((char *)file.first.get(), file.second);
|
||||
engine = fl::FllImporter().fromString(str);
|
||||
armyLossPersentageVariable = engine->getInputVariable("armyLoss");
|
||||
armyGrowthVariable = engine->getInputVariable("armyGrowth");
|
||||
heroRoleVariable = engine->getInputVariable("heroRole");
|
||||
dangerVariable = engine->getInputVariable("danger");
|
||||
turnVariable = engine->getInputVariable("turn");
|
||||
@ -164,7 +166,7 @@ uint64_t getCreatureBankArmyReward(const CGObjectInstance * target, const CGHero
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t getDwellingScore(CCallback * cb, const CGObjectInstance * target, bool checkGold)
|
||||
uint64_t getDwellingArmyValue(CCallback * cb, const CGObjectInstance * target, bool checkGold)
|
||||
{
|
||||
auto dwelling = dynamic_cast<const CGDwelling *>(target);
|
||||
uint64_t score = 0;
|
||||
@ -185,6 +187,27 @@ uint64_t getDwellingScore(CCallback * cb, const CGObjectInstance * target, bool
|
||||
return score;
|
||||
}
|
||||
|
||||
uint64_t getDwellingArmyGrowth(CCallback * cb, const CGObjectInstance * target, PlayerColor myColor)
|
||||
{
|
||||
auto dwelling = dynamic_cast<const CGDwelling *>(target);
|
||||
uint64_t score = 0;
|
||||
|
||||
if(dwelling->getOwner() == myColor)
|
||||
return 0;
|
||||
|
||||
for(auto & creLevel : dwelling->creatures)
|
||||
{
|
||||
if(creLevel.second.size())
|
||||
{
|
||||
auto creature = creLevel.second.back().toCreature();
|
||||
|
||||
score += creature->getAIValue() * creature->getGrowth();
|
||||
}
|
||||
}
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
int getDwellingArmyCost(const CGObjectInstance * target)
|
||||
{
|
||||
auto dwelling = dynamic_cast<const CGDwelling *>(target);
|
||||
@ -272,7 +295,7 @@ uint64_t RewardEvaluator::getArmyReward(
|
||||
case Obj::CREATURE_GENERATOR2:
|
||||
case Obj::CREATURE_GENERATOR3:
|
||||
case Obj::CREATURE_GENERATOR4:
|
||||
return getDwellingScore(ai->cb.get(), target, checkGold);
|
||||
return getDwellingArmyValue(ai->cb.get(), target, checkGold);
|
||||
case Obj::CRYPT:
|
||||
case Obj::SHIPWRECK:
|
||||
case Obj::SHIPWRECK_SURVIVOR:
|
||||
@ -293,6 +316,44 @@ uint64_t RewardEvaluator::getArmyReward(
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t RewardEvaluator::getArmyGrowth(
|
||||
const CGObjectInstance * target,
|
||||
const CGHeroInstance * hero,
|
||||
const CCreatureSet * army) const
|
||||
{
|
||||
const float enemyArmyEliminationRewardRatio = 0.5f;
|
||||
|
||||
if(!target)
|
||||
return 0;
|
||||
|
||||
switch(target->ID)
|
||||
{
|
||||
case Obj::TOWN:
|
||||
{
|
||||
auto town = dynamic_cast<const CGTownInstance *>(target);
|
||||
auto fortLevel = town->fortLevel();
|
||||
auto neutral = !town->getOwner().isValidPlayer();
|
||||
auto booster = isAnotherAi(town, *ai->cb) || neutral ? 1 : 2;
|
||||
|
||||
if(fortLevel < CGTownInstance::CITADEL)
|
||||
return town->hasFort() ? booster * 500 : 0;
|
||||
else
|
||||
return booster * (fortLevel == CGTownInstance::CASTLE ? 5000 : 2000);
|
||||
}
|
||||
|
||||
case Obj::CREATURE_GENERATOR1:
|
||||
case Obj::CREATURE_GENERATOR2:
|
||||
case Obj::CREATURE_GENERATOR3:
|
||||
case Obj::CREATURE_GENERATOR4:
|
||||
return getDwellingArmyGrowth(ai->cb.get(), target, hero->getOwner());
|
||||
case Obj::ARTIFACT:
|
||||
// it is not supported now because hero will not sit in town on 7th day but later parts of legion may be counted as army growth as well.
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int RewardEvaluator::getGoldCost(const CGObjectInstance * target, const CGHeroInstance * hero, const CCreatureSet * army) const
|
||||
{
|
||||
if(!target)
|
||||
@ -714,6 +775,7 @@ public:
|
||||
{
|
||||
evaluationContext.goldReward += evaluationContext.evaluator.getGoldReward(target, hero);
|
||||
evaluationContext.armyReward += evaluationContext.evaluator.getArmyReward(target, hero, army, checkGold);
|
||||
evaluationContext.armyGrowth += evaluationContext.evaluator.getArmyGrowth(target, hero, army);
|
||||
evaluationContext.skillReward += evaluationContext.evaluator.getSkillReward(target, hero, evaluationContext.heroRole);
|
||||
evaluationContext.strategicalValue += evaluationContext.evaluator.getStrategicalValue(target);
|
||||
evaluationContext.goldCost += evaluationContext.evaluator.getGoldCost(target, hero, army);
|
||||
@ -920,6 +982,7 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task)
|
||||
scoutTurnDistanceVariable->setValue(evaluationContext.movementCostByRole[HeroRole::SCOUT]);
|
||||
goldRewardVariable->setValue(evaluationContext.goldReward);
|
||||
armyRewardVariable->setValue(evaluationContext.armyReward);
|
||||
armyGrowthVariable->setValue(evaluationContext.armyGrowth);
|
||||
skillRewardVariable->setValue(evaluationContext.skillReward);
|
||||
dangerVariable->setValue(evaluationContext.danger);
|
||||
rewardTypeVariable->setValue(rewardType);
|
||||
|
@ -33,6 +33,7 @@ public:
|
||||
RewardEvaluator(const Nullkiller * ai) : ai(ai) {}
|
||||
|
||||
uint64_t getArmyReward(const CGObjectInstance * target, const CGHeroInstance * hero, const CCreatureSet * army, bool checkGold) const;
|
||||
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;
|
||||
@ -54,6 +55,7 @@ struct DLL_EXPORT EvaluationContext
|
||||
float closestWayRatio;
|
||||
float armyLossPersentage;
|
||||
float armyReward;
|
||||
uint64_t armyGrowth;
|
||||
int32_t goldReward;
|
||||
int32_t goldCost;
|
||||
float skillReward;
|
||||
@ -95,6 +97,7 @@ private:
|
||||
fl::InputVariable * turnVariable;
|
||||
fl::InputVariable * goldRewardVariable;
|
||||
fl::InputVariable * armyRewardVariable;
|
||||
fl::InputVariable * armyGrowthVariable;
|
||||
fl::InputVariable * dangerVariable;
|
||||
fl::InputVariable * skillRewardVariable;
|
||||
fl::InputVariable * strategicalValueVariable;
|
||||
|
@ -879,7 +879,7 @@ void AINodeStorage::setHeroes(std::map<const CGHeroInstance *, HeroRole> heroes)
|
||||
for(auto & hero : heroes)
|
||||
{
|
||||
// do not allow our own heroes in garrison to act on map
|
||||
if(hero.first->getOwner() == ai->playerID && hero.first->inTownGarrison && ai->isHeroLocked(hero.first))
|
||||
if(hero.first->getOwner() == ai->playerID && hero.first->inTownGarrison)
|
||||
continue;
|
||||
|
||||
uint64_t mask = FirstActorMask << actors.size();
|
||||
|
@ -121,106 +121,39 @@ InputVariable: fear
|
||||
term: LOW Triangle 0.000 0.500 1.000
|
||||
term: MEDIUM Triangle 0.500 1.000 1.500
|
||||
term: HIGH Ramp 1.000 1.800
|
||||
InputVariable: armyGrowth
|
||||
enabled: true
|
||||
range: 0.000 20000.000
|
||||
lock-range: false
|
||||
term: NONE Ramp 100.000 0.000
|
||||
term: SMALL Triangle 0.000 1000.000 3000.000
|
||||
term: MEDIUM Triangle 1000.000 3000.000 8000.000
|
||||
term: BIG Triangle 3000.000 8000.000 20000.000
|
||||
term: HUGE Ramp 8000.000 20000.000
|
||||
OutputVariable: Value
|
||||
enabled: true
|
||||
range: -0.500 1.500
|
||||
range: -1.500 2.000
|
||||
lock-range: false
|
||||
aggregation: AlgebraicSum
|
||||
defuzzifier: Centroid 100
|
||||
default: 0.500
|
||||
lock-previous: false
|
||||
term: LOWEST Discrete -0.500 0.000 -0.500 1.000 -0.200 1.000 -0.200 0.000 0.200 0.000 0.200 1.000 0.500 1.000 0.500 0.000 0.500
|
||||
term: BITLOW Rectangle -0.010 0.010 0.500
|
||||
term: LOW Discrete -0.150 0.000 -0.150 1.000 -0.050 1.000 -0.050 0.000 0.050 0.000 0.050 1.000 0.150 1.000 0.150 0.000 0.500
|
||||
term: MEDIUM Triangle 0.450 0.500 0.550 0.050
|
||||
term: HIGH Discrete 0.850 0.000 0.850 1.000 0.950 1.000 0.950 0.000 1.050 0.000 1.050 1.000 1.150 1.000 1.150 0.000 0.500
|
||||
term: HIGHEST Discrete 0.500 0.000 0.500 1.000 0.800 1.000 0.800 0.000 1.200 0.000 1.200 1.000 1.500 1.000 1.500 0.000 0.500
|
||||
term: BITHIGH Rectangle 0.990 1.010 0.500
|
||||
term: WORST Binary -1.000 -inf 0.500
|
||||
term: BAD Rectangle -1.000 -0.700 0.500
|
||||
term: BASE Rectangle -0.200 0.200 0.400
|
||||
term: LOW Rectangle 1.110 1.190 0.320
|
||||
term: HIGHEST Discrete 0.300 0.000 0.300 1.000 0.600 1.000 0.600 0.000 1.700 0.000 1.700 1.000 2.000 1.000 2.000 0.000 0.500
|
||||
term: HIGH Discrete 0.600 0.000 0.600 1.000 0.850 1.000 0.850 0.000 1.450 0.000 1.450 1.000 1.700 1.000 1.700 0.000 0.400
|
||||
term: BITHIGH Discrete 0.850 0.000 0.850 1.000 1.000 1.000 1.000 0.000 1.300 0.000 1.300 1.000 1.450 1.000 1.450 0.000 0.350
|
||||
term: MEDIUM Discrete 1.000 0.000 1.000 1.000 1.100 1.000 1.100 0.000 1.200 0.000 1.200 1.000 1.300 1.000 1.300 0.000 0.330
|
||||
RuleBlock: gold reward
|
||||
enabled: true
|
||||
conjunction: AlgebraicProduct
|
||||
disjunction: AlgebraicSum
|
||||
implication: AlgebraicProduct
|
||||
activation: General
|
||||
rule: if turn is NOW and mainTurnDistance is very LONG and heroRole is SCOUT then Value is LOW with 0.5
|
||||
rule: if turn is NOW and mainTurnDistance is LONG and heroRole is SCOUT then Value is LOW with 0.3
|
||||
rule: if turn is NOW and scoutTurnDistance is LONG and heroRole is SCOUT then Value is LOW with 0.3
|
||||
rule: if turn is NOW and mainTurnDistance is LONG and heroRole is MAIN then Value is LOW with 0.3
|
||||
rule: if turn is NEXT and mainTurnDistance is very LONG and heroRole is SCOUT then Value is LOW with 0.8
|
||||
rule: if turn is NEXT and scoutTurnDistance is LONG and heroRole is SCOUT then Value is BITLOW
|
||||
rule: if turn is NEXT and mainTurnDistance is LONG and heroRole is MAIN then Value is LOW with 0.3
|
||||
rule: if turn is NEXT and mainTurnDistance is LONG and heroRole is SCOUT then Value is BITLOW with 0.3
|
||||
rule: if turn is FUTURE and scoutTurnDistance is very LONG and heroRole is SCOUT then Value is LOWEST with 0.3
|
||||
rule: if turn is FUTURE and mainTurnDistance is very LONG and heroRole is SCOUT then Value is LOWEST with 0.5
|
||||
rule: if turn is FUTURE and mainTurnDistance is very LONG and heroRole is MAIN and strategicalValue is NONE then Value is LOWEST with 0.5
|
||||
rule: if turn is FUTURE and mainTurnDistance is very LONG and heroRole is MAIN and strategicalValue is LOW then Value is LOWEST with 0.3
|
||||
rule: if turn is FUTURE and mainTurnDistance is very LONG and heroRole is MAIN and strategicalValue is MEDIUM then Value is LOW with 0.5
|
||||
rule: if turn is FUTURE and mainTurnDistance is very LONG and heroRole is MAIN and strategicalValue is HIGH then Value is BITLOW
|
||||
rule: if turn is FUTURE and scoutTurnDistance is LONG and heroRole is SCOUT then Value is LOW
|
||||
rule: if turn is FUTURE and mainTurnDistance is LONG and heroRole is MAIN then Value is LOW
|
||||
rule: if turn is FUTURE and mainTurnDistance is LONG and heroRole is SCOUT then Value is LOW
|
||||
rule: if scoutTurnDistance is MEDIUM and heroRole is SCOUT then Value is BITLOW
|
||||
rule: if mainTurnDistance is MEDIUM then Value is BITLOW
|
||||
rule: if scoutTurnDistance is LOW and heroRole is SCOUT then Value is MEDIUM
|
||||
rule: if mainTurnDistance is LOW then Value is MEDIUM
|
||||
rule: if goldReward is HIGH and goldPreasure is HIGH and heroRole is SCOUT and danger is not NONE and armyLoss is LOW then Value is BITHIGH
|
||||
rule: if goldReward is HIGH and goldPreasure is HIGH and heroRole is SCOUT and danger is NONE then Value is HIGH with 0.7
|
||||
rule: if goldReward is HIGH and goldPreasure is HIGH and heroRole is MAIN and danger is not NONE and armyLoss is LOW and fear is not HIGH then Value is HIGHEST
|
||||
rule: if goldReward is HIGH and goldPreasure is HIGH and heroRole is MAIN and danger is NONE then Value is BITHIGH
|
||||
rule: if goldReward is MEDIUM and goldPreasure is HIGH and heroRole is SCOUT and danger is NONE then Value is HIGH
|
||||
rule: if goldReward is MEDIUM and goldPreasure is HIGH and armyLoss is LOW and heroRole is SCOUT and danger is not NONE then Value is MEDIUM
|
||||
rule: if goldReward is MEDIUM and heroRole is MAIN and danger is NONE and rewardType is SINGLE then Value is BITLOW
|
||||
rule: if goldReward is MEDIUM and goldPreasure is HIGH and armyLoss is LOW and heroRole is MAIN and danger is not NONE then Value is BITHIGH
|
||||
rule: if goldReward is LOW and goldPreasure is HIGH and heroRole is SCOUT and armyLoss is LOW then Value is BITHIGH
|
||||
rule: if goldReward is LOW and heroRole is MAIN and danger is not NONE and rewardType is SINGLE and armyLoss is LOW then Value is BITLOW
|
||||
rule: if goldReward is LOW and heroRole is MAIN and danger is NONE and rewardType is SINGLE then Value is LOW
|
||||
rule: if goldReward is LOWEST and heroRole is MAIN and danger is NONE and rewardType is SINGLE then Value is LOWEST
|
||||
rule: if armyReward is HIGH and heroRole is SCOUT and danger is not NONE and armyLoss is LOW then Value is HIGH with 0.5
|
||||
rule: if armyReward is HIGH and heroRole is SCOUT and danger is NONE then Value is HIGHEST
|
||||
rule: if armyReward is HIGH and heroRole is MAIN and rewardType is MIXED and armyLoss is LOW and fear is not HIGH then Value is HIGHEST
|
||||
rule: if armyReward is HIGH and heroRole is MAIN and rewardType is SINGLE and mainTurnDistance is LOWEST then Value is HIGHEST
|
||||
rule: if armyReward is HIGH and heroRole is MAIN and rewardType is SINGLE and danger is NONE and fear is not HIGH then Value is HIGH
|
||||
rule: if armyReward is HIGH and heroRole is MAIN and rewardType is SINGLE and danger is not NONE and armyLoss is LOW and fear is not HIGH then Value is HIGHEST
|
||||
rule: if armyReward is MEDIUM and heroRole is MAIN and danger is not NONE and armyLoss is LOW and fear is not HIGH then Value is HIGHEST with 0.5
|
||||
rule: if armyReward is MEDIUM and heroRole is MAIN and danger is NONE then Value is BITHIGH
|
||||
rule: if armyReward is MEDIUM and heroRole is MAIN and danger is NONE and mainTurnDistance is LOWEST then Value is HIGH with 0.2
|
||||
rule: if armyReward is MEDIUM and heroRole is SCOUT and danger is NONE then Value is HIGHEST with 0.5
|
||||
rule: if armyReward is LOW and heroRole is SCOUT and danger is NONE then Value is HIGH
|
||||
rule: if armyReward is LOW and heroRole is MAIN and danger is not NONE and armyLoss is LOW then Value is HIGH
|
||||
rule: if armyReward is LOW and heroRole is MAIN and danger is NONE then Value is BITLOW with 0.5
|
||||
rule: if armyReward is LOW and heroRole is MAIN and danger is NONE and mainTurnDistance is LOWEST then Value is HIGH
|
||||
rule: if skillReward is LOW and heroRole is MAIN and armyLoss is LOW then Value is BITHIGH
|
||||
rule: if skillReward is MEDIUM and heroRole is MAIN and armyLoss is LOW and fear is not HIGH then Value is BITHIGH
|
||||
rule: if skillReward is MEDIUM and heroRole is MAIN and rewardType is MIXED and armyLoss is LOW and fear is not HIGH then Value is HIGH with 0.5
|
||||
rule: if skillReward is HIGH and heroRole is MAIN and armyLoss is LOW and fear is not HIGH then Value is HIGH
|
||||
rule: if skillReward is MEDIUM and heroRole is SCOUT then Value is LOWEST
|
||||
rule: if skillReward is HIGH and heroRole is SCOUT then Value is LOWEST
|
||||
rule: if strategicalValue is LOW and heroRole is MAIN and armyLoss is LOW then Value is BITHIGH
|
||||
rule: if strategicalValue is LOWEST and heroRole is MAIN and armyLoss is LOW then Value is LOW
|
||||
rule: if strategicalValue is LOW and heroRole is SCOUT and armyLoss is LOW and fear is not HIGH then Value is HIGH with 0.5
|
||||
rule: if strategicalValue is MEDIUM and heroRole is SCOUT and danger is NONE and fear is not HIGH then Value is HIGH
|
||||
rule: if strategicalValue is HIGH and heroRole is SCOUT and danger is NONE and fear is not HIGH then Value is HIGHEST with 0.5
|
||||
rule: if strategicalValue is HIGH and heroRole is MAIN and armyLoss is LOW and fear is not HIGH then Value is HIGHEST
|
||||
rule: if strategicalValue is HIGH and heroRole is MAIN and armyLoss is MEDIUM and fear is not HIGH then Value is HIGH
|
||||
rule: if strategicalValue is MEDIUM and heroRole is MAIN and armyLoss is LOW and fear is not HIGH then Value is HIGH
|
||||
rule: if rewardType is NONE then Value is LOWEST
|
||||
rule: if armyLoss is HIGH and strategicalValue is not HIGH and heroRole is MAIN then Value is LOWEST
|
||||
rule: if armyLoss is HIGH and strategicalValue is HIGH and heroRole is MAIN then Value is LOW
|
||||
rule: if armyLoss is HIGH and heroRole is SCOUT then Value is LOWEST
|
||||
rule: if heroRole is SCOUT and closestHeroRatio is LOW then Value is LOW
|
||||
rule: if heroRole is SCOUT and closestHeroRatio is LOWEST then Value is LOWEST
|
||||
rule: if heroRole is MAIN and danger is NONE and skillReward is NONE and rewardType is SINGLE and closestHeroRatio is LOW then Value is LOW
|
||||
rule: if heroRole is MAIN and danger is NONE and skillReward is NONE and rewardType is SINGLE and closestHeroRatio is LOWEST then Value is LOWEST
|
||||
rule: if heroRole is MAIN and danger is not NONE and armyLoss is LOW then Value is BITHIGH with 0.2
|
||||
rule: if heroRole is SCOUT then Value is BITLOW
|
||||
rule: if goldCost is not NONE and goldReward is NONE and goldPreasure is HIGH then Value is LOWEST
|
||||
rule: if turn is NOW then Value is LOW with 0.3
|
||||
rule: if turn is not NOW then Value is LOW with 0.4
|
||||
rule: if goldPreasure is HIGH and goldReward is HIGH and heroRole is MAIN and danger is not NONE and armyLoss is LOW and fear is not HIGH then Value is HIGHEST
|
||||
rule: if goldPreasure is HIGH and goldReward is MEDIUM and heroRole is MAIN and danger is not NONE and armyLoss is LOW and fear is not HIGH then Value is HIGH
|
||||
rule: if goldPreasure is HIGH and goldReward is HIGH and heroRole is SCOUT and danger is NONE and armyLoss is LOW and fear is not HIGH then Value is HIGHEST
|
||||
rule: if goldPreasure is HIGH and goldReward is MEDIUM and heroRole is SCOUT and danger is NONE and armyLoss is LOW and fear is not HIGH then Value is HIGH
|
||||
rule: if goldPreasure is HIGH and goldReward is LOW and heroRole is SCOUT and armyLoss is LOW then Value is BITHIGH
|
||||
rule: if goldPreasure is HIGH and goldReward is LOW and heroRole is SCOUT and scoutTurnDistance is LOW and armyLoss is LOW then Value is HIGH with 0.5
|
||||
rule: if fear is MEDIUM then Value is LOW
|
||||
rule: if fear is HIGH then Value is LOWEST
|
||||
rule: if heroRole is MAIN then Value is BASE
|
||||
rule: if heroRole is SCOUT then Value is BASE
|
||||
rule: if heroRole is MAIN and armyGrowth is HUGE then Value is HIGH
|
||||
rule: if heroRole is MAIN and armyGrowth is BIG then Value is BITHIGH
|
||||
rule: if heroRole is MAIN and strategicalValue is HIGH then Value is HIGHEST
|
Loading…
Reference in New Issue
Block a user