diff --git a/AI/VCAI/Fuzzy.cpp b/AI/VCAI/Fuzzy.cpp index 2c3e84d8a..1fbe2aa6e 100644 --- a/AI/VCAI/Fuzzy.cpp +++ b/AI/VCAI/Fuzzy.cpp @@ -129,20 +129,14 @@ TacticalAdvantageEngine::TacticalAdvantageEngine() { try { - ourShooters = new fl::InputVariable("OurShooters"); - ourWalkers = new fl::InputVariable("OurWalkers"); - ourFlyers = new fl::InputVariable("OurFlyers"); - enemyShooters = new fl::InputVariable("EnemyShooters"); - enemyWalkers = new fl::InputVariable("EnemyWalkers"); - enemyFlyers = new fl::InputVariable("EnemyFlyers"); + ourShooters = vstd::make_unique(fl::InputVariable("OurShooters")); + ourWalkers = vstd::make_unique(fl::InputVariable("OurWalkers")); + ourFlyers = vstd::make_unique(fl::InputVariable("OurFlyers")); + enemyShooters = vstd::make_unique(fl::InputVariable("EnemyShooters")); + enemyWalkers = vstd::make_unique(fl::InputVariable("EnemyWalkers")); + enemyFlyers = vstd::make_unique(fl::InputVariable("EnemyFlyers")); - //Tactical advantage calculation - std::vector helper = - { - ourShooters, ourWalkers, ourFlyers, enemyShooters, enemyWalkers, enemyFlyers - }; - - for(auto val : helper) + for(auto val : {ourShooters.get(), ourWalkers.get(), ourFlyers.get(), enemyShooters.get(), enemyWalkers.get(), enemyFlyers.get()}) { engine.addInputVariable(val); val->addTerm(new fl::Ramp("FEW", 0.6, 0.0)); @@ -150,12 +144,10 @@ TacticalAdvantageEngine::TacticalAdvantageEngine() val->setRange(0.0, 1.0); } - ourSpeed = new fl::InputVariable("OurSpeed"); - enemySpeed = new fl::InputVariable("EnemySpeed"); + ourSpeed = vstd::make_unique(fl::InputVariable("OurSpeed")); + enemySpeed = vstd::make_unique(fl::InputVariable("EnemySpeed")); - helper = { ourSpeed, enemySpeed }; - - for(auto val : helper) + for(auto val : {ourSpeed.get(), enemySpeed.get()}) { engine.addInputVariable(val); val->addTerm(new fl::Ramp("LOW", 6.5, 3)); @@ -164,8 +156,8 @@ TacticalAdvantageEngine::TacticalAdvantageEngine() val->setRange(0, 25); } - castleWalls = new fl::InputVariable("CastleWalls"); - engine.addInputVariable(castleWalls); + castleWalls = vstd::make_unique(fl::InputVariable("CastleWalls")); + engine.addInputVariable(castleWalls.get()); { fl::Rectangle * none = new fl::Rectangle("NONE", CGTownInstance::NONE, CGTownInstance::NONE + (CGTownInstance::FORT - CGTownInstance::NONE) * 0.5f); castleWalls->addTerm(none); @@ -181,8 +173,8 @@ TacticalAdvantageEngine::TacticalAdvantageEngine() } - bankPresent = new fl::InputVariable("Bank"); - engine.addInputVariable(bankPresent); + bankPresent = vstd::make_unique(fl::InputVariable("Bank")); + engine.addInputVariable(bankPresent.get()); { fl::Rectangle * termFalse = new fl::Rectangle("FALSE", 0.0, 0.5f); bankPresent->addTerm(termFalse); @@ -191,8 +183,8 @@ TacticalAdvantageEngine::TacticalAdvantageEngine() bankPresent->setRange(0, 1); } - threat = new fl::OutputVariable("Threat"); - engine.addOutputVariable(threat); + threat = vstd::make_unique(fl::OutputVariable("Threat")); + engine.addOutputVariable(threat.get()); threat->addTerm(new fl::Ramp("LOW", 1, MIN_AI_STRENGHT)); threat->addTerm(new fl::Triangle("MEDIUM", 0.8, 1.2)); threat->addTerm(new fl::Ramp("HIGH", 1, 1.5)); @@ -265,12 +257,13 @@ float TacticalAdvantageEngine::getTacticalAdvantage(const CArmedInstance * we, c if(output < 0 || (output != output)) { - fl::InputVariable * tab[] = { bankPresent, castleWalls, ourWalkers, ourShooters, ourFlyers, ourSpeed, enemyWalkers, enemyShooters, enemyFlyers, enemySpeed }; + fl::scalar tab[] = { bankPresent->getValue(), castleWalls->getValue(), ourWalkers->getValue(), ourShooters->getValue(), ourFlyers->getValue(), ourSpeed->getValue(), + enemyWalkers->getValue(), enemyShooters->getValue(), enemyFlyers->getValue(), enemySpeed->getValue() }; std::string names[] = { "bankPresent", "castleWalls", "ourWalkers", "ourShooters", "ourFlyers", "ourSpeed", "enemyWalkers", "enemyShooters", "enemyFlyers", "enemySpeed" }; std::stringstream log("Warning! Fuzzy engine doesn't cover this set of parameters: "); for(int i = 0; i < boost::size(tab); i++) - log << names[i] << ": " << tab[i]->getValue() << " "; + log << names[i] << ": " << tab[i] << " "; logAi->error(log.str()); assert(false); } @@ -278,22 +271,6 @@ float TacticalAdvantageEngine::getTacticalAdvantage(const CArmedInstance * we, c return output; } -TacticalAdvantageEngine::~TacticalAdvantageEngine() -{ - //TODO: smart pointers? - delete ourWalkers; - delete ourShooters; - delete ourFlyers; - delete enemyWalkers; - delete enemyShooters; - delete enemyFlyers; - delete ourSpeed; - delete enemySpeed; - delete bankPresent; - delete castleWalls; - delete threat; -} - //std::shared_ptr chooseSolution (std::vector> & vec) Goals::TSubgoal FuzzyHelper::chooseSolution(Goals::TGoalVec vec) @@ -334,20 +311,19 @@ HeroMovementGoalEngineBase::HeroMovementGoalEngineBase() { try { - strengthRatio = new fl::InputVariable("strengthRatio"); //hero must be strong enough to defeat guards - heroStrength = new fl::InputVariable("heroStrength"); //we want to use weakest possible hero - turnDistance = new fl::InputVariable("turnDistance"); //we want to use hero who is near - missionImportance = new fl::InputVariable("lockedMissionImportance"); //we may want to preempt hero with low-priority mission - value = new fl::OutputVariable("Value"); + strengthRatio = vstd::make_unique(fl::InputVariable("strengthRatio")); //hero must be strong enough to defeat guards + heroStrength = vstd::make_unique(fl::InputVariable("heroStrength")); //we want to use weakest possible hero + turnDistance = vstd::make_unique(fl::InputVariable("turnDistance")); //we want to use hero who is near + missionImportance = vstd::make_unique(fl::InputVariable("lockedMissionImportance")); //we may want to preempt hero with low-priority mission + value = vstd::make_unique(fl::OutputVariable("Value")); value->setMinimum(0); value->setMaximum(5); - std::vector helper = { strengthRatio, heroStrength, turnDistance, missionImportance }; - for(auto val : helper) + for(auto val : { strengthRatio.get(), heroStrength.get(), turnDistance.get(), missionImportance.get() }) { engine.addInputVariable(val); } - engine.addOutputVariable(value); + engine.addOutputVariable(value.get()); strengthRatio->addTerm(new fl::Ramp("LOW", SAFE_ATTACK_CONSTANT, 0)); strengthRatio->addTerm(new fl::Ramp("HIGH", SAFE_ATTACK_CONSTANT, SAFE_ATTACK_CONSTANT * 3)); @@ -427,14 +403,6 @@ void HeroMovementGoalEngineBase::setSharedFuzzyVariables(Goals::AbstractGoal & g } } -HeroMovementGoalEngineBase::~HeroMovementGoalEngineBase() -{ - delete strengthRatio; - delete heroStrength; - delete turnDistance; - delete missionImportance; -} - float FuzzyHelper::evaluate(Goals::VisitTile & g) { return visitTileEngine.evaluate(g); @@ -524,9 +492,9 @@ GetObjEngine::GetObjEngine() { try { - objectValue = new fl::InputVariable("objectValue"); //value of that object type known by AI + objectValue = vstd::make_unique(fl::InputVariable("objectValue")); //value of that object type known by AI - engine.addInputVariable(objectValue); + engine.addInputVariable(objectValue.get()); //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 @@ -553,11 +521,6 @@ GetObjEngine::GetObjEngine() configure(); } -GetObjEngine::~GetObjEngine() -{ - delete objectValue; -} - float GetObjEngine::evaluate(Goals::AbstractGoal & goal) { auto g = dynamic_cast(goal); @@ -603,10 +566,6 @@ VisitTileEngine::VisitTileEngine() //so far no VisitTile-specific variables that configure(); } -VisitTileEngine::~VisitTileEngine() -{ -} - float VisitTileEngine::evaluate(Goals::AbstractGoal & goal) { auto g = dynamic_cast(goal); diff --git a/AI/VCAI/Fuzzy.h b/AI/VCAI/Fuzzy.h index 6fd969605..2460a99a0 100644 --- a/AI/VCAI/Fuzzy.h +++ b/AI/VCAI/Fuzzy.h @@ -33,13 +33,12 @@ public: TacticalAdvantageEngine(); float getTacticalAdvantage(const CArmedInstance * we, const CArmedInstance * enemy); //returns factor how many times enemy is stronger than us - ~TacticalAdvantageEngine(); private: - fl::InputVariable * ourWalkers, *ourShooters, *ourFlyers, *enemyWalkers, *enemyShooters, *enemyFlyers; - fl::InputVariable * ourSpeed, *enemySpeed; - fl::InputVariable * bankPresent; - fl::InputVariable * castleWalls; - fl::OutputVariable * threat; + std::unique_ptr ourWalkers, ourShooters, ourFlyers, enemyWalkers, enemyShooters, enemyFlyers; + std::unique_ptr ourSpeed, enemySpeed; + std::unique_ptr bankPresent; + std::unique_ptr castleWalls; + std::unique_ptr threat; }; class HeroMovementGoalEngineBase : public engineBase //in future - maybe derive from some (GoalEngineBase : public engineBase) class for handling non-movement goals with common utility for goal engines @@ -48,16 +47,15 @@ public: HeroMovementGoalEngineBase(); virtual float evaluate(Goals::AbstractGoal & goal) = 0; - virtual ~HeroMovementGoalEngineBase(); protected: void setSharedFuzzyVariables(Goals::AbstractGoal & goal); - fl::InputVariable * strengthRatio; - fl::InputVariable * heroStrength; - fl::InputVariable * turnDistance; - fl::InputVariable * missionImportance; - fl::OutputVariable * value; + std::unique_ptr strengthRatio; + std::unique_ptr heroStrength; + std::unique_ptr turnDistance; + std::unique_ptr missionImportance; + std::unique_ptr value; private: float calculateTurnDistanceInputValue(const CGHeroInstance * h, int3 tile) const; @@ -67,7 +65,6 @@ class VisitTileEngine : public HeroMovementGoalEngineBase { public: VisitTileEngine(); - ~VisitTileEngine(); float evaluate(Goals::AbstractGoal & goal) override; }; @@ -75,10 +72,9 @@ class GetObjEngine : public HeroMovementGoalEngineBase { public: GetObjEngine(); - ~GetObjEngine(); float evaluate(Goals::AbstractGoal & goal) override; protected: - fl::InputVariable * objectValue; + std::unique_ptr objectValue; }; class FuzzyHelper