1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-29 21:56:54 +02:00

Merge pull request #493 from dydzio0614/FuzzyEvaluationFixes

Fuzzy evaluation fixes
This commit is contained in:
Alexander Shishkin 2018-10-10 22:00:14 +03:00 committed by GitHub
commit 6958f2cddf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -26,7 +26,7 @@ engineBase::engineBase()
void engineBase::configure()
{
engine.configure("Minimum", "Maximum", "Minimum", "AlgebraicSum", "Centroid", "General");
engine.configure("Minimum", "Maximum", "Minimum", "AlgebraicSum", "Centroid", "Proportional");
logAi->info(engine.toString());
}
@ -168,17 +168,17 @@ TacticalAdvantageEngine::TacticalAdvantageEngine()
addRule("if OurSpeed is LOW and EnemyShooters is MANY then Threat is HIGH");
addRule("if OurSpeed is HIGH and EnemyShooters is MANY then Threat is LOW");
addRule("if OurWalkers is FEW and EnemyShooters is MANY then Threat is somewhat LOW");
addRule("if OurShooters is MANY and EnemySpeed is HIGH then Threat is somewhat HIGH");
addRule("if OurWalkers is FEW and EnemyShooters is MANY then Threat is LOW");
addRule("if OurShooters is MANY and EnemySpeed is HIGH then Threat is HIGH");
//just to cover all cases
addRule("if OurShooters is FEW and EnemySpeed is HIGH then Threat is MEDIUM");
addRule("if EnemySpeed is MEDIUM then Threat is MEDIUM");
addRule("if EnemySpeed is LOW and OurShooters is FEW then Threat is MEDIUM");
addRule("if Bank is TRUE and OurShooters is MANY then Threat is somewhat HIGH");
addRule("if Bank is TRUE and OurShooters is MANY then Threat is HIGH");
addRule("if Bank is TRUE and EnemyShooters is MANY then Threat is LOW");
addRule("if CastleWalls is HIGH and OurWalkers is MANY then Threat is very HIGH");
addRule("if CastleWalls is HIGH and OurWalkers is MANY then Threat is HIGH");
addRule("if CastleWalls is HIGH and OurFlyers is MANY and OurShooters is MANY then Threat is MEDIUM");
addRule("if CastleWalls is MEDIUM and OurShooters is MANY and EnemyWalkers is MANY then Threat is LOW");
@ -269,7 +269,7 @@ HeroMovementGoalEngineBase::HeroMovementGoalEngineBase()
strengthRatio->setRange(0, SAFE_ATTACK_CONSTANT * 3);
//strength compared to our main hero
heroStrength->addTerm(new fl::Ramp("LOW", 0.2, 0));
heroStrength->addTerm(new fl::Ramp("LOW", 0.5, 0));
heroStrength->addTerm(new fl::Triangle("MEDIUM", 0.2, 0.8));
heroStrength->addTerm(new fl::Ramp("HIGH", 0.5, 1));
heroStrength->setRange(0.0, 1.0);
@ -292,19 +292,19 @@ HeroMovementGoalEngineBase::HeroMovementGoalEngineBase()
value->setRange(0.0, 5.0);
//use unarmed scouts if possible
addRule("if strengthRatio is HIGH and heroStrength is LOW then Value is very HIGH");
addRule("if strengthRatio is HIGH and heroStrength is LOW then Value is HIGH");
//we may want to use secondary hero(es) rather than main hero
addRule("if strengthRatio is HIGH and heroStrength is MEDIUM then Value is somewhat HIGH");
addRule("if strengthRatio is HIGH and heroStrength is HIGH then Value is somewhat LOW");
addRule("if strengthRatio is HIGH and heroStrength is MEDIUM then Value is MEDIUM");
addRule("if strengthRatio is HIGH and heroStrength is HIGH then Value is LOW");
//don't assign targets to heroes who are too weak, but prefer targets of our main hero (in case we need to gather army)
addRule("if strengthRatio is LOW and heroStrength is LOW then Value is very LOW");
addRule("if strengthRatio is LOW and heroStrength is LOW then Value is LOW");
//attempt to arm secondary heroes is not stupid
addRule("if strengthRatio is LOW and heroStrength is MEDIUM then Value is somewhat HIGH");
addRule("if strengthRatio is LOW and heroStrength is MEDIUM then Value is HIGH");
addRule("if strengthRatio is LOW and heroStrength is HIGH then Value is LOW");
//do not cancel important goals
addRule("if lockedMissionImportance is HIGH then Value is very LOW");
addRule("if lockedMissionImportance is MEDIUM then Value is somewhat LOW");
addRule("if lockedMissionImportance is HIGH then Value is LOW");
addRule("if lockedMissionImportance is MEDIUM then Value is MEDIUM");
addRule("if lockedMissionImportance is LOW then Value is HIGH");
//pick nearby objects if it's easy, avoid long walks
addRule("if turnDistance is SHORT then Value is HIGH");
@ -350,11 +350,12 @@ VisitObjEngine::VisitObjEngine()
engine.addInputVariable(objectValue);
//objectValue ranges are based on checking RMG priorities of some objects and trying to guess sane value ranges
objectValue->addTerm(new fl::Ramp("LOW", 3000, 0)); //I have feeling that concave shape might work well instead of ramp for objectValue FL terms
objectValue->addTerm(new fl::Triangle("MEDIUM", 2500, 6000));
objectValue->addTerm(new fl::Ramp("HIGH", 5000, 20000));
objectValue->setRange(0, 20000); //relic artifact value is border value by design, even better things are scaled down.
//objectValue ranges are based on checking RMG priorities of some objects and checking LOW/MID/HIGH proportions for various values in QtFuzzyLite
objectValue->addTerm(new fl::Ramp("LOW", 3500.0, 0.0));
objectValue->addTerm(new fl::Triangle("MEDIUM", 0.0, 8500.0));
std::vector<fl::Discrete::Pair> multiRamp = { fl::Discrete::Pair(5000.0, 0.0), fl::Discrete::Pair(10000.0, 0.75), fl::Discrete::Pair(20000.0, 1.0) };
objectValue->addTerm(new fl::Discrete("HIGH", multiRamp));
objectValue->setRange(0.0, 20000.0); //relic artifact value is border value by design, even better things are scaled down.
addRule("if objectValue is HIGH then Value is HIGH");
addRule("if objectValue is MEDIUM then Value is MEDIUM");