1
0
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:
DjWarmonger 2013-12-19 20:21:21 +00:00
parent 29f4a12814
commit 983c0496d0
6 changed files with 137 additions and 4 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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;