mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Some work towards fuzzy goal comparison.
This commit is contained in:
parent
29f4a12814
commit
983c0496d0
@ -278,14 +278,14 @@ float FuzzyHelper::getTacticalAdvantage (const CArmedInstance *we, const CArmedI
|
||||
}
|
||||
|
||||
//shared_ptr<AbstractGoal> chooseSolution (std::vector<shared_ptr<AbstractGoal>> & vec)
|
||||
Goals::TSubgoal chooseSolution (Goals::TGoalVec & vec)
|
||||
Goals::TSubgoal FuzzyHelper::chooseSolution (Goals::TGoalVec & vec)
|
||||
{
|
||||
typedef std::pair<Goals::TSubgoal, float> goalValue;
|
||||
std::vector <goalValue> values;
|
||||
|
||||
for (auto g : vec)
|
||||
{
|
||||
values.push_back (std::make_pair(g, 66.6f));
|
||||
values.push_back (std::make_pair(g, g->accept(this)));
|
||||
}
|
||||
|
||||
auto compareGoals = [&](const goalValue & lhs, const goalValue & rhs) -> bool
|
||||
@ -296,3 +296,45 @@ Goals::TSubgoal chooseSolution (Goals::TGoalVec & vec)
|
||||
boost::sort (values, compareGoals);
|
||||
return values.end()->first;
|
||||
}
|
||||
|
||||
float FuzzyHelper::evaluate (Goals::Explore & g)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::RecruitHero & g)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::VisitTile & g)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::VisitHero & g)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::BuildThis & g)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::DigAtTile & g)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::CollectRes & g)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::Build & g)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::Invalid & g)
|
||||
{
|
||||
return -1e10;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::AbstractGoal & g)
|
||||
{
|
||||
logAi->debugStream() << boost::format("Cannot evaluate goal %s") % g.name();
|
||||
return -1e10;
|
||||
}
|
@ -42,6 +42,17 @@ public:
|
||||
void initBank();
|
||||
void initTacticalAdvantage();
|
||||
|
||||
float evaluate (Goals::Explore & g);
|
||||
float evaluate (Goals::RecruitHero & g);
|
||||
float evaluate (Goals::VisitTile & g);
|
||||
float evaluate (Goals::VisitHero & g);
|
||||
float evaluate (Goals::BuildThis & g);
|
||||
float evaluate (Goals::DigAtTile & g);
|
||||
float evaluate (Goals::CollectRes & g);
|
||||
float evaluate (Goals::Build & g);
|
||||
float evaluate (Goals::Invalid & g);
|
||||
float evaluate (Goals::AbstractGoal & g);
|
||||
|
||||
ui64 estimateBankDanger (int ID);
|
||||
float getTacticalAdvantage (const CArmedInstance *we, const CArmedInstance *enemy); //returns factor how many times enemy is stronger than us
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "StdInc.h"
|
||||
#include "Goals.h"
|
||||
#include "VCAI.h"
|
||||
#include "Fuzzy.h"
|
||||
|
||||
/*
|
||||
* Goals.cpp, part of VCMI engine
|
||||
@ -89,6 +90,17 @@ namespace Goals
|
||||
{
|
||||
ai->tryRealize(static_cast<Build&>(*this));
|
||||
}
|
||||
template <>
|
||||
float CGoal<Win>::accept (FuzzyHelper * f)
|
||||
{
|
||||
return f->evaluate(static_cast<Win&>(*this));
|
||||
}
|
||||
|
||||
template <>
|
||||
float CGoal<Build>::accept (FuzzyHelper * f)
|
||||
{
|
||||
return f->evaluate(static_cast<Build&>(*this));
|
||||
}
|
||||
}
|
||||
|
||||
//TSubgoal AbstractGoal::whatToDoToAchieve()
|
||||
@ -497,6 +509,23 @@ TSubgoal VisitTile::whatToDoToAchieve()
|
||||
}
|
||||
}
|
||||
|
||||
TGoalVec VisitTile::getAllPossibleSubgoals()
|
||||
{
|
||||
TGoalVec ret;
|
||||
if (!cb->isVisible(tile))
|
||||
ret.push_back (sptr(Goals::Explore())); //what sense does it make?
|
||||
else
|
||||
{
|
||||
for (auto h : cb->getHeroesInfo())
|
||||
{
|
||||
ret.push_back (sptr(Goals::VisitTile(tile).sethero(h)));
|
||||
}
|
||||
if (ai->canRecruitAnyHero())
|
||||
ret.push_back (sptr(Goals::RecruitHero()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
TSubgoal DigAtTile::whatToDoToAchieve()
|
||||
{
|
||||
const CGObjectInstance *firstObj = frontOrNull(cb->getVisitableObjs(tile));
|
||||
@ -879,9 +908,22 @@ void AbstractGoal::accept (VCAI * ai)
|
||||
ai->tryRealize(*this);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void CGoal<T>::accept (VCAI * ai)
|
||||
{
|
||||
ai->tryRealize(static_cast<T&>(*this)); //casting enforces template instantiation
|
||||
}
|
||||
|
||||
float AbstractGoal::accept (FuzzyHelper * f)
|
||||
{
|
||||
return f->evaluate(*this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
float CGoal<T>::accept (FuzzyHelper * f)
|
||||
{
|
||||
return f->evaluate(static_cast<T&>(*this)); //casting enforces template instantiation
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
struct HeroPtr;
|
||||
class VCAI;
|
||||
class FuzzyHelper;
|
||||
|
||||
namespace Goals
|
||||
{
|
||||
@ -100,10 +101,12 @@ public:
|
||||
static TSubgoal lookForArtSmart(int aid); //checks non-standard ways of obtaining art (merchants, quests, etc.)
|
||||
static TSubgoal tryRecruitHero();
|
||||
|
||||
virtual TGoalVec getAllPossibleSubgoals() = 0;
|
||||
virtual TSubgoal whatToDoToAchieve() = 0;
|
||||
///Visitor pattern
|
||||
//TODO: make accept work for shared_ptr... somehow
|
||||
virtual void accept (VCAI * ai); //unhandled goal will report standard error
|
||||
virtual float accept (FuzzyHelper * f);
|
||||
|
||||
virtual bool operator== (AbstractGoal &g)
|
||||
{
|
||||
@ -155,6 +158,7 @@ public:
|
||||
OSETTER(int, bid)
|
||||
|
||||
void accept (VCAI * ai) override;
|
||||
float accept (FuzzyHelper * f) override;
|
||||
|
||||
CGoal<T> * clone() const override
|
||||
{
|
||||
@ -180,30 +184,35 @@ class Invalid : public CGoal<Invalid>
|
||||
{
|
||||
public:
|
||||
Invalid() : CGoal (Goals::INVALID){};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class Win : public CGoal<Win>
|
||||
{
|
||||
public:
|
||||
Win() : CGoal (Goals::WIN){};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class NotLose : public CGoal<NotLose>
|
||||
{
|
||||
public:
|
||||
NotLose() : CGoal (Goals::DO_NOT_LOSE){};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class Conquer : public CGoal<Conquer>
|
||||
{
|
||||
public:
|
||||
Conquer() : CGoal (Goals::CONQUER){};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class Build : public CGoal<Build>
|
||||
{
|
||||
public:
|
||||
Build() : CGoal (Goals::BUILD){};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class Explore : public CGoal<Explore>
|
||||
@ -211,6 +220,7 @@ class Explore : public CGoal<Explore>
|
||||
public:
|
||||
Explore() : CGoal (Goals::EXPLORE){};
|
||||
Explore(HeroPtr h) : CGoal (Goals::EXPLORE){hero = h;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
std::string completeMessage() const override;
|
||||
};
|
||||
@ -220,6 +230,7 @@ private:
|
||||
GatherArmy() : CGoal (Goals::GATHER_ARMY){};
|
||||
public:
|
||||
GatherArmy(int val) : CGoal (Goals::GATHER_ARMY){value = val;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
std::string completeMessage() const override;
|
||||
};
|
||||
@ -227,12 +238,14 @@ class BoostHero : public CGoal<BoostHero>
|
||||
{
|
||||
public:
|
||||
BoostHero() : CGoal (Goals::INVALID){}; //TODO
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class RecruitHero : public CGoal<RecruitHero>
|
||||
{
|
||||
public:
|
||||
RecruitHero() : CGoal (Goals::RECRUIT_HERO){};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class BuildThis : public CGoal<BuildThis>
|
||||
@ -242,6 +255,7 @@ private:
|
||||
public:
|
||||
BuildThis(BuildingID Bid, const CGTownInstance *tid) : CGoal (Goals::BUILD_STRUCTURE) {bid = Bid; town = tid;};
|
||||
BuildThis(BuildingID Bid) : CGoal (Goals::BUILD_STRUCTURE) {bid = Bid;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class CollectRes : public CGoal<CollectRes>
|
||||
@ -250,6 +264,7 @@ private:
|
||||
CollectRes() : CGoal (Goals::COLLECT_RES){};
|
||||
public:
|
||||
CollectRes(int rid, int val) : CGoal (Goals::COLLECT_RES) {resID = rid; value = val;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class GatherTroops : public CGoal<GatherTroops>
|
||||
@ -258,6 +273,7 @@ private:
|
||||
GatherTroops() : CGoal (Goals::GATHER_TROOPS){};
|
||||
public:
|
||||
GatherTroops(int type, int val) : CGoal (Goals::GATHER_TROOPS){objid = type; value = val;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class GetObj : public CGoal<GetObj>
|
||||
@ -266,6 +282,7 @@ private:
|
||||
GetObj() {}; // empty constructor not allowed
|
||||
public:
|
||||
GetObj(int Objid) : CGoal(Goals::GET_OBJ) {objid = Objid;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
bool operator== (GetObj &g) {return g.objid == objid;}
|
||||
bool fulfillsMe (shared_ptr<VisitTile> goal) override;
|
||||
@ -278,6 +295,7 @@ private:
|
||||
public:
|
||||
FindObj(int ID) : CGoal(Goals::FIND_OBJ) {objid = ID;};
|
||||
FindObj(int ID, int subID) : CGoal(Goals::FIND_OBJ) {objid = ID; resID = subID;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class VisitHero : public CGoal<VisitHero>
|
||||
@ -286,6 +304,7 @@ private:
|
||||
VisitHero() : CGoal (Goals::VISIT_HERO){};
|
||||
public:
|
||||
VisitHero(int hid) : CGoal (Goals::VISIT_HERO){objid = hid;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
bool operator== (VisitHero &g) {return g.objid == objid;}
|
||||
bool fulfillsMe (shared_ptr<VisitTile> goal) override;
|
||||
@ -297,6 +316,7 @@ private:
|
||||
GetArtOfType() : CGoal (Goals::GET_ART_TYPE){};
|
||||
public:
|
||||
GetArtOfType(int type) : CGoal (Goals::GET_ART_TYPE){aid = type;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class VisitTile : public CGoal<VisitTile>
|
||||
@ -306,6 +326,7 @@ private:
|
||||
VisitTile() {}; // empty constructor not allowed
|
||||
public:
|
||||
VisitTile(int3 Tile) : CGoal (Goals::VISIT_TILE) {tile = Tile;};
|
||||
TGoalVec getAllPossibleSubgoals() override;
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
bool operator== (VisitTile &g) {return g.tile == tile;}
|
||||
std::string completeMessage() const override;
|
||||
@ -314,6 +335,7 @@ class ClearWayTo : public CGoal<ClearWayTo>
|
||||
{
|
||||
public:
|
||||
ClearWayTo(int3 Tile) : CGoal (Goals::CLEAR_WAY_TO) {tile = Tile;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
bool operator== (ClearWayTo &g) {return g.tile == tile;}
|
||||
};
|
||||
@ -324,6 +346,7 @@ private:
|
||||
DigAtTile() : CGoal (Goals::DIG_AT_TILE){};
|
||||
public:
|
||||
DigAtTile(int3 Tile) : CGoal (Goals::DIG_AT_TILE) {tile = Tile;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
bool operator== (DigAtTile &g) {return g.tile == tile;}
|
||||
};
|
||||
@ -334,6 +357,7 @@ class CIssueCommand : public CGoal<CIssueCommand>
|
||||
|
||||
public:
|
||||
CIssueCommand(std::function<bool()> _command): CGoal(ISSUE_COMMAND), command(_command) {}
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
|
||||
|
@ -1130,6 +1130,19 @@ std::vector<const CGObjectInstance *> VCAI::getPossibleDestinations(HeroPtr h)
|
||||
return possibleDestinations;
|
||||
}
|
||||
|
||||
bool VCAI::canRecruitAnyHero (const CGTownInstance * t) const
|
||||
{
|
||||
//TODO: make gathering gold, building tavern or conquering town (?) possible subgoals
|
||||
if (!t)
|
||||
t = findTownWithTavern();
|
||||
if (t)
|
||||
return cb->getResourceAmount(Res::GOLD) >= HERO_GOLD_COST &&
|
||||
cb->getHeroesInfo().size() < ALLOWED_ROAMING_HEROES &&
|
||||
cb->getAvailableHeroes(t).size();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void VCAI::wander(HeroPtr h)
|
||||
{
|
||||
while(1)
|
||||
@ -1181,7 +1194,7 @@ void VCAI::wander(HeroPtr h)
|
||||
striveToGoal(sptr(Goals::VisitTile(t->visitablePos()).sethero(h)));
|
||||
if (pos1 == h->pos && h == primaryHero()) //hero can't move
|
||||
{
|
||||
if(cb->getResourceAmount(Res::GOLD) >= HERO_GOLD_COST && cb->getHeroesInfo().size() < ALLOWED_ROAMING_HEROES && cb->getAvailableHeroes(t).size())
|
||||
if (canRecruitAnyHero(t))
|
||||
recruitHero(t);
|
||||
}
|
||||
break;
|
||||
|
@ -274,6 +274,7 @@ public:
|
||||
bool isAccessibleForHero(const int3 & pos, HeroPtr h, bool includeAllies = false) const;
|
||||
|
||||
const CGTownInstance *findTownWithTavern() const;
|
||||
bool canRecruitAnyHero(const CGTownInstance * t = NULL) const;
|
||||
|
||||
std::vector<HeroPtr> getUnblockedHeroes() const;
|
||||
HeroPtr primaryHero() const;
|
||||
|
Loading…
Reference in New Issue
Block a user