mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-26 08:41:13 +02:00
Taken JCrada patch as it is.
This commit is contained in:
parent
b0cd4f4117
commit
9ca991282a
@ -87,17 +87,23 @@ FuzzyHelper::FuzzyHelper()
|
||||
logAi->infoStream() << engine.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FuzzyHelper::initBank()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
//Trivial bank estimation
|
||||
bankInput = new fl::InputVariable("BankInput");
|
||||
bankDanger = new fl::OutputVariable("BankDanger");
|
||||
bankDanger->setMinimum(0);
|
||||
//SingletonTerm (4.0) is a Rectangle (5.0) within 5*Macheps
|
||||
bankInput->addTerm(new fl::Rectangle("SET", 0.5 - 5 * fl::fuzzylite::macheps(),
|
||||
0.5 + 5 * fl::fuzzylite::macheps()));
|
||||
|
||||
bankInput->setRange(0.5 - 5 * fl::fuzzylite::macheps(), 0.5 + 5 * fl::fuzzylite::macheps());
|
||||
|
||||
bankDanger = new fl::OutputVariable("BankDanger");
|
||||
|
||||
engine.addInputVariable(bankInput);
|
||||
engine.addOutputVariable(bankDanger);
|
||||
engine.addRuleBlock(&bankBlock);
|
||||
@ -106,6 +112,7 @@ void FuzzyHelper::initBank()
|
||||
bankDanger->addTerm(new fl::Triangle("Bank" + boost::lexical_cast<std::string>(i), 0, 1));
|
||||
bankBlock.addRule(fl::Rule::parse("if BankInput is SET then BankDanger is Bank" + boost::lexical_cast<std::string>(i), &engine));
|
||||
}
|
||||
bankDanger->setRange(0.0, 1.0);
|
||||
}
|
||||
catch (fl::Exception & fe)
|
||||
{
|
||||
@ -136,6 +143,7 @@ void FuzzyHelper::initTacticalAdvantage()
|
||||
engine.addInputVariable(val);
|
||||
val->addTerm(new fl::Ramp("FEW", 0.6, 0.0));
|
||||
val->addTerm(new fl::Ramp("MANY", 0.4, 1));
|
||||
val->setRange(0.0, 1.0);
|
||||
}
|
||||
|
||||
ta.ourSpeed = new fl::InputVariable("OurSpeed");
|
||||
@ -149,35 +157,59 @@ void FuzzyHelper::initTacticalAdvantage()
|
||||
val->addTerm(new fl::Ramp("LOW", 6.5, 3));
|
||||
val->addTerm(new fl::Triangle("MEDIUM", 5.5, 10.5));
|
||||
val->addTerm(new fl::Ramp("HIGH", 8.5, 16));
|
||||
val->setRange(3.0, 16.0);
|
||||
}
|
||||
|
||||
ta.castleWalls = new fl::InputVariable("CastleWalls");
|
||||
engine.addInputVariable(ta.castleWalls);
|
||||
ta.castleWalls->addTerm(new fl::Rectangle("NONE", CGTownInstance::NONE - 5.0 * fl::fuzzylite::macheps(),
|
||||
CGTownInstance::NONE + 5.0 * fl::fuzzylite::macheps()));
|
||||
{
|
||||
fl::Rectangle* none = new fl::Rectangle("NONE",
|
||||
CGTownInstance::NONE - 5.0 * fl::fuzzylite::macheps(),
|
||||
CGTownInstance::NONE + 5.0 * fl::fuzzylite::macheps());
|
||||
ta.castleWalls->addTerm(none);
|
||||
|
||||
fl::scalar a = CGTownInstance::FORT, d = 2.5;
|
||||
fl::scalar b = a + (d - a) * 1.0 / 5.0;
|
||||
fl::scalar c = a + (d - a) * 4.0 / 5.0;
|
||||
ta.castleWalls->addTerm(new fl::Trapezoid("MEDIUM", a, b, c, d));
|
||||
fl::Trapezoid* medium = new fl::Trapezoid("MEDIUM", a, b, c, d);
|
||||
ta.castleWalls->addTerm(medium);
|
||||
|
||||
fl::Ramp* high = new fl::Ramp("HIGH", CGTownInstance::CITADEL - 0.1, CGTownInstance::CASTLE);
|
||||
ta.castleWalls->addTerm(high);
|
||||
|
||||
ta.castleWalls->setRange(
|
||||
std::min({none->getStart(),none->getEnd(),
|
||||
medium->getVertexA(), medium->getVertexD(),
|
||||
high->getStart(), high->getEnd()}),
|
||||
std::max({none->getStart(),none->getEnd(),
|
||||
medium->getVertexA(), medium->getVertexD(),
|
||||
high->getStart(), high->getEnd()}));
|
||||
}
|
||||
|
||||
ta.castleWalls->addTerm(new fl::Ramp("HIGH", CGTownInstance::CITADEL - 0.1, CGTownInstance::CASTLE));
|
||||
|
||||
|
||||
ta.bankPresent = new fl::InputVariable("Bank");
|
||||
engine.addInputVariable(ta.bankPresent);
|
||||
ta.bankPresent->addTerm(new fl::Rectangle("FALSE", 0.0 - 5.0 * fl::fuzzylite::macheps(),
|
||||
0.0 + 5.0 * fl::fuzzylite::macheps()));
|
||||
ta.bankPresent->addTerm(new fl::Rectangle("TRUE", 1.0 - 5.0 * fl::fuzzylite::macheps(),
|
||||
0.0 + 5.0 * fl::fuzzylite::macheps()));
|
||||
{
|
||||
fl::Rectangle* termFalse = new fl::Rectangle("FALSE", 0.0 - 5.0 * fl::fuzzylite::macheps(),
|
||||
0.0 + 5.0 * fl::fuzzylite::macheps());
|
||||
ta.bankPresent->addTerm(termFalse);
|
||||
fl::Rectangle* termTrue = new fl::Rectangle("TRUE", 1.0 - 5.0 * fl::fuzzylite::macheps(),
|
||||
0.0 + 5.0 * fl::fuzzylite::macheps());
|
||||
ta.bankPresent->addTerm(termTrue);
|
||||
ta.bankPresent->setRange(
|
||||
std::min({termFalse->getStart(),termFalse->getEnd(),
|
||||
termTrue->getStart(), termTrue->getEnd()}),
|
||||
std::max({termFalse->getStart(),termFalse->getEnd(),
|
||||
termTrue->getStart(), termTrue->getEnd()}));
|
||||
}
|
||||
|
||||
ta.threat = new fl::OutputVariable("Threat");
|
||||
ta.threat->setMinimum(0);
|
||||
ta.threat->setMaximum(3);
|
||||
engine.addOutputVariable(ta.threat);
|
||||
ta.threat->addTerm(new fl::Ramp("LOW", 1, MIN_AI_STRENGHT));
|
||||
ta.threat->addTerm(new fl::Triangle("MEDIUM", 0.8, 1.2));
|
||||
ta.threat->addTerm(new fl::Ramp("HIGH", 1, 1.5));
|
||||
ta.threat->setRange(MIN_AI_STRENGHT, 1.5);
|
||||
|
||||
engine.addRuleBlock(&ta.tacticalAdvantage);
|
||||
|
||||
@ -221,6 +253,20 @@ ui64 FuzzyHelper::estimateBankDanger (const CBank * bank)
|
||||
bank0->setVertexC(info->minGuards().totalStrength * 1.5f);
|
||||
bank1->setVertexA(info->maxGuards().totalStrength * 0.5f);
|
||||
bank1->setVertexC(info->maxGuards().totalStrength * 1.5f);
|
||||
|
||||
fl::scalar min = std::min(
|
||||
{bank0->getVertexA(), bank0->getVertexC(),
|
||||
bank1->getVertexA(), bank1->getVertexC()});
|
||||
fl::scalar max = std::max(
|
||||
{bank0->getVertexA(), bank0->getVertexC(),
|
||||
bank1->getVertexA(), bank1->getVertexC()});
|
||||
|
||||
if (fl::Op::isLt(min, bankDanger->getMinimum())){
|
||||
bankDanger->setMinimum(min);
|
||||
}
|
||||
if (fl::Op::isGt(max, bankDanger->getMaximum())){
|
||||
bankDanger->setMaximum(max);
|
||||
}
|
||||
}
|
||||
|
||||
//comparison purposes
|
||||
@ -366,25 +412,30 @@ void FuzzyHelper::initVisitTile()
|
||||
|
||||
vt.strengthRatio->addTerm(new fl::Ramp("LOW", SAFE_ATTACK_CONSTANT, 0));
|
||||
vt.strengthRatio->addTerm(new fl::Ramp("HIGH", SAFE_ATTACK_CONSTANT, SAFE_ATTACK_CONSTANT * 3));
|
||||
vt.strengthRatio->setRange(0,SAFE_ATTACK_CONSTANT * 3 );
|
||||
|
||||
//strength compared to our main hero
|
||||
vt.heroStrength->addTerm(new fl::Ramp("LOW", 0.2, 0));
|
||||
vt.heroStrength->addTerm(new fl::Triangle("MEDIUM", 0.2, 0.8));
|
||||
vt.heroStrength->addTerm(new fl::Ramp("HIGH", 0.5, 1));
|
||||
vt.heroStrength->setRange(0.0,1.0);
|
||||
|
||||
vt.turnDistance->addTerm(new fl::Ramp("SMALL", 0.5, 0));
|
||||
vt.turnDistance->addTerm(new fl::Triangle("MEDIUM", 0.1, 0.8));
|
||||
vt.turnDistance->addTerm(new fl::Ramp("LONG", 0.5, 3));
|
||||
vt.turnDistance->setRange(0.0, 3.0);
|
||||
|
||||
vt.missionImportance->addTerm(new fl::Ramp("LOW", 2.5, 0));
|
||||
vt.missionImportance->addTerm(new fl::Triangle("MEDIUM", 2, 3));
|
||||
vt.missionImportance->addTerm(new fl::Ramp("HIGH", 2.5, 5));
|
||||
vt.missionImportance->setRange(0.0, 5.0);
|
||||
|
||||
//an issue: in 99% cases this outputs center of mass (2.5) regardless of actual input :/
|
||||
//should be same as "mission Importance" to keep consistency
|
||||
vt.value->addTerm(new fl::Ramp("LOW", 2.5, 0));
|
||||
vt.value->addTerm(new fl::Triangle("MEDIUM", 2, 3)); //can't be center of mass :/
|
||||
vt.value->addTerm(new fl::Ramp("HIGH", 2.5, 5));
|
||||
vt.value->setRange(0.0,5.0);
|
||||
|
||||
engine.addRuleBlock (&vt.rules);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user