1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-26 22:57:00 +02:00

Some more logging for goal completion.

Stub of fuzzy goal selection.
This commit is contained in:
DjWarmonger 2013-11-24 08:21:51 +00:00
parent 0ab7b498f5
commit cedb3ea82a
5 changed files with 96 additions and 17 deletions

View File

@ -5,6 +5,8 @@
#include "../../lib/CObjectHandler.h" #include "../../lib/CObjectHandler.h"
#include "../../lib/CCreatureHandler.h" #include "../../lib/CCreatureHandler.h"
#include "../../lib/VCMI_Lib.h" #include "../../lib/VCMI_Lib.h"
//#include "Goals.h"
//#include "VCAI.h"
/* /*
* Fuzzy.cpp, part of VCMI engine * Fuzzy.cpp, part of VCMI engine
@ -25,6 +27,7 @@ class CGTownInstance;
using namespace boost::assign; using namespace boost::assign;
using namespace vstd; using namespace vstd;
//using namespace Goals;
FuzzyHelper *fh; FuzzyHelper *fh;
@ -273,3 +276,22 @@ float FuzzyHelper::getTacticalAdvantage (const CArmedInstance *we, const CArmedI
} }
return output; return output;
} }
//shared_ptr<AbstractGoal> chooseSolution (std::vector<shared_ptr<AbstractGoal>> & vec)
//{
// typedef std::pair<shared_ptr<AbstractGoal>, float> goalValue;
// std::vector <goalValue> values;
//
// for (auto g : vec)
// {
// values.push_back (std::make_pair(g, 66.6f));
// }
//
// auto compareGoals = [&](const goalValue & lhs, const goalValue & rhs) -> bool
// {
// return lhs.second < rhs.second;
// };
//
// boost::sort (values, compareGoals);
// return values.end()->first;
//}

View File

@ -13,6 +13,9 @@
class VCAI; class VCAI;
class CArmedInstance; class CArmedInstance;
//class TSubgoal;
//class TGoalVec;
//class AbstractGoal;
class FuzzyHelper class FuzzyHelper
{ {
@ -40,4 +43,8 @@ public:
ui64 estimateBankDanger (int ID); ui64 estimateBankDanger (int ID);
float getTacticalAdvantage (const CArmedInstance *we, const CArmedInstance *enemy); //returns factor how many times enemy is stronger than us float getTacticalAdvantage (const CArmedInstance *we, const CArmedInstance *enemy); //returns factor how many times enemy is stronger than us
//FIXME: use Goals namespace
//Goals::TSubgoal chooseSolution (Goals::TGoalVec & vec);
//shared_ptr<AbstractGoal> chooseSolution (std::vector<shared_ptr<AbstractGoal>> & vec);
}; };

View File

@ -196,6 +196,11 @@ TSubgoal FindObj::whatToDoToAchieve()
else else
return sptr (Goals::Explore()); return sptr (Goals::Explore());
} }
std::string GetObj::completeMessage() const
{
return "hero " + hero.get()->name + " captured Object ID = " + boost::lexical_cast<std::string>(objid);
}
TSubgoal GetObj::whatToDoToAchieve() TSubgoal GetObj::whatToDoToAchieve()
{ {
const CGObjectInstance * obj = cb->getObj(ObjectInstanceID(objid)); const CGObjectInstance * obj = cb->getObj(ObjectInstanceID(objid));
@ -205,6 +210,11 @@ TSubgoal GetObj::whatToDoToAchieve()
return sptr (Goals::VisitTile(pos)); return sptr (Goals::VisitTile(pos));
} }
std::string VisitHero::completeMessage() const
{
return "hero " + hero.get()->name + " visited hero " + boost::lexical_cast<std::string>(objid);
}
TSubgoal VisitHero::whatToDoToAchieve() TSubgoal VisitHero::whatToDoToAchieve()
{ {
const CGObjectInstance * obj = cb->getObj(ObjectInstanceID(objid)); const CGObjectInstance * obj = cb->getObj(ObjectInstanceID(objid));
@ -214,6 +224,7 @@ TSubgoal VisitHero::whatToDoToAchieve()
if (hero && ai->isAccessibleForHero(pos, hero, true) && isSafeToVisit(hero, pos)) //enemy heroes can get reinforcements if (hero && ai->isAccessibleForHero(pos, hero, true) && isSafeToVisit(hero, pos)) //enemy heroes can get reinforcements
{ {
assert (hero->pos != pos); //don't try to visit yourself
settile(pos).setisElementar(true); settile(pos).setisElementar(true);
return sptr (*this); return sptr (*this);
} }
@ -278,6 +289,11 @@ TSubgoal ClearWayTo::whatToDoToAchieve()
throw cannotFulfillGoalException("Cannot reach given tile!"); //how and when could this be used? throw cannotFulfillGoalException("Cannot reach given tile!"); //how and when could this be used?
} }
std::string Explore::completeMessage() const
{
return "Hero " + hero.get()->name + " completed exploration";
};
TSubgoal Explore::whatToDoToAchieve() TSubgoal Explore::whatToDoToAchieve()
{ {
auto objs = ai->visitableObjs; //try to use buildings that uncover map auto objs = ai->visitableObjs; //try to use buildings that uncover map
@ -403,6 +419,11 @@ TSubgoal RecruitHero::whatToDoToAchieve()
return iAmElementar(); return iAmElementar();
} }
std::string VisitTile::completeMessage() const
{
return "Hero " + hero.get()->name + " visited tile " + tile();
}
TSubgoal VisitTile::whatToDoToAchieve() TSubgoal VisitTile::whatToDoToAchieve()
{ {
if(!cb->isVisible(tile)) if(!cb->isVisible(tile))
@ -676,6 +697,11 @@ TSubgoal Invalid::whatToDoToAchieve()
return iAmElementar(); return iAmElementar();
} }
std::string GatherArmy::completeMessage() const
{
return "Hero " + hero.get()->name + " gathered army of value " + boost::lexical_cast<std::string>(value);
};
TSubgoal GatherArmy::whatToDoToAchieve() TSubgoal GatherArmy::whatToDoToAchieve()
{ {
//TODO: find hero if none set //TODO: find hero if none set

View File

@ -23,6 +23,7 @@ namespace Goals
{ {
struct AbstractGoal; struct AbstractGoal;
typedef std::shared_ptr<Goals::AbstractGoal> TSubgoal; typedef std::shared_ptr<Goals::AbstractGoal> TSubgoal;
typedef std::vector<TSubgoal> TGoalVec;
enum EGoals enum EGoals
{ {
@ -90,6 +91,7 @@ public:
EGoals goalType; EGoals goalType;
std::string name() const; std::string name() const;
virtual std::string completeMessage() const {return "This goal is unspecified!";};
bool invalid() const; bool invalid() const;
@ -101,13 +103,8 @@ public:
//TODO: make accept work for shared_ptr... somehow //TODO: make accept work for shared_ptr... somehow
virtual void accept (VCAI * ai); //unhandled goal will report standard error virtual void accept (VCAI * ai); //unhandled goal will report standard error
bool operator== (AbstractGoal &g) //TODO: virtualize - comparison returns true only for same subclasses virtual bool operator== (AbstractGoal &g) //TODO: virtualize - comparison returns true only for same subclasses
{ {
switch (goalType)
{
case EGoals::GET_OBJ:
return objid == g.objid;
}
return false; return false;
} }
@ -149,12 +146,12 @@ public:
void accept (VCAI * ai) override void accept (VCAI * ai) override
{ {
ai->tryRealize(static_cast<T&>(*this)); ai->tryRealize(static_cast<T&>(*this)); //casting enforces template instantiation
} }
CGoal<T> * clone() const override CGoal<T> * clone() const override
{ {
return new T(static_cast<T const&>(*this)); return new T(static_cast<T const&>(*this)); //casting enforces template instantiation
} }
TSubgoal iAmElementar() TSubgoal iAmElementar()
{ {
@ -209,6 +206,7 @@ class Explore : public CGoal<Explore>
Explore() : CGoal (Goals::EXPLORE){}; Explore() : CGoal (Goals::EXPLORE){};
Explore(HeroPtr h) : CGoal (Goals::EXPLORE){hero = h;}; Explore(HeroPtr h) : CGoal (Goals::EXPLORE){hero = h;};
TSubgoal whatToDoToAchieve() override; TSubgoal whatToDoToAchieve() override;
std::string completeMessage() const override;
}; };
class GatherArmy : public CGoal<GatherArmy> class GatherArmy : public CGoal<GatherArmy>
{ {
@ -217,6 +215,7 @@ private:
public: public:
GatherArmy(int val) : CGoal (Goals::GATHER_ARMY){value = val;}; GatherArmy(int val) : CGoal (Goals::GATHER_ARMY){value = val;};
TSubgoal whatToDoToAchieve() override; TSubgoal whatToDoToAchieve() override;
std::string completeMessage() const override;
}; };
class BoostHero : public CGoal<BoostHero> class BoostHero : public CGoal<BoostHero>
{ {
@ -257,17 +256,19 @@ public:
}; };
class GetObj : public CGoal<GetObj> class GetObj : public CGoal<GetObj>
{ {
private: private:
GetObj() {}; // empty constructor not allowed GetObj() {}; // empty constructor not allowed
public: public:
GetObj(int Objid) : CGoal(Goals::GET_OBJ) {objid = Objid;}; GetObj(int Objid) : CGoal(Goals::GET_OBJ) {objid = Objid;};
TSubgoal whatToDoToAchieve() override; TSubgoal whatToDoToAchieve() override;
bool operator== (GetObj &g) {return g.objid == objid;}
std::string completeMessage() const override;
}; };
class FindObj : public CGoal<FindObj> class FindObj : public CGoal<FindObj>
{ {
private: private:
FindObj() {}; // empty constructor not allowed FindObj() {}; // empty constructor not allowed
public: public:
FindObj(int ID) : CGoal(Goals::FIND_OBJ) {objid = ID;}; FindObj(int ID) : CGoal(Goals::FIND_OBJ) {objid = ID;};
FindObj(int ID, int subID) : CGoal(Goals::FIND_OBJ) {objid = ID; resID = subID;}; FindObj(int ID, int subID) : CGoal(Goals::FIND_OBJ) {objid = ID; resID = subID;};
TSubgoal whatToDoToAchieve() override; TSubgoal whatToDoToAchieve() override;
@ -279,6 +280,8 @@ private:
public: public:
VisitHero(int hid) : CGoal (Goals::VISIT_HERO){objid = hid;}; VisitHero(int hid) : CGoal (Goals::VISIT_HERO){objid = hid;};
TSubgoal whatToDoToAchieve() override; TSubgoal whatToDoToAchieve() override;
bool operator== (VisitHero &g) {return g.objid == objid;}
std::string completeMessage() const override;
}; };
class GetArtOfType : public CGoal<GetArtOfType> class GetArtOfType : public CGoal<GetArtOfType>
{ {
@ -296,12 +299,15 @@ private:
public: public:
VisitTile(int3 Tile) : CGoal (Goals::VISIT_TILE) {tile = Tile;}; VisitTile(int3 Tile) : CGoal (Goals::VISIT_TILE) {tile = Tile;};
TSubgoal whatToDoToAchieve() override; TSubgoal whatToDoToAchieve() override;
bool operator== (VisitTile &g) {return g.tile == tile;}
std::string completeMessage() const override;
}; };
class ClearWayTo : public CGoal<ClearWayTo> class ClearWayTo : public CGoal<ClearWayTo>
{ {
public: public:
ClearWayTo(int3 Tile) : CGoal (Goals::CLEAR_WAY_TO) {tile = Tile;}; ClearWayTo(int3 Tile) : CGoal (Goals::CLEAR_WAY_TO) {tile = Tile;};
TSubgoal whatToDoToAchieve() override; TSubgoal whatToDoToAchieve() override;
bool operator== (ClearWayTo &g) {return g.tile == tile;}
}; };
class DigAtTile : public CGoal<DigAtTile> class DigAtTile : public CGoal<DigAtTile>
//elementar with hero on tile //elementar with hero on tile
@ -311,6 +317,7 @@ private:
public: public:
DigAtTile(int3 Tile) : CGoal (Goals::DIG_AT_TILE) {tile = Tile;}; DigAtTile(int3 Tile) : CGoal (Goals::DIG_AT_TILE) {tile = Tile;};
TSubgoal whatToDoToAchieve() override; TSubgoal whatToDoToAchieve() override;
bool operator== (DigAtTile &g) {return g.tile == tile;}
}; };
class CIssueCommand : public CGoal<CIssueCommand> class CIssueCommand : public CGoal<CIssueCommand>

View File

@ -1226,13 +1226,29 @@ void VCAI::setGoal(HeroPtr h, Goals::TSubgoal goal)
void VCAI::completeGoal (Goals::TSubgoal goal) void VCAI::completeGoal (Goals::TSubgoal goal)
{ {
logAi->debugStream() << boost::format("Completing goal: %s") % goal->name();
if (const CGHeroInstance * h = goal->hero.get(true)) if (const CGHeroInstance * h = goal->hero.get(true))
{ {
auto it = lockedHeroes.find(h); auto it = lockedHeroes.find(h);
if (it != lockedHeroes.end()) if (it != lockedHeroes.end())
if (it->second->goalType == goal->goalType) if (it->second == goal)
{
logAi->debugStream() << boost::format("%s") % goal->completeMessage();
lockedHeroes.erase(it); //goal fulfilled, free hero lockedHeroes.erase(it); //goal fulfilled, free hero
}
} }
else //complete goal for all heroes maybe?
{
for (auto p : lockedHeroes)
{
if (p.second == goal)
{
logAi->debugStream() << boost::format("%s") % goal->completeMessage();
lockedHeroes.erase (lockedHeroes.find(p.first)); //is it safe?
}
}
}
} }
void VCAI::battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) void VCAI::battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side)
@ -1407,6 +1423,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
bool ret = false; bool ret = false;
if(startHpos == dst) if(startHpos == dst)
{ {
//FIXME: this assertion fails also if AI moves onto defeated guarded object
assert(cb->getVisitableObjs(dst).size() > 1); //there's no point in revisiting tile where there is no visitable object assert(cb->getVisitableObjs(dst).size() > 1); //there's no point in revisiting tile where there is no visitable object
cb->moveHero(*h, CGHeroInstance::convertPosition(dst, true)); cb->moveHero(*h, CGHeroInstance::convertPosition(dst, true));
waitTillFree(); //movement may cause battle or blocking dialog waitTillFree(); //movement may cause battle or blocking dialog
@ -1420,7 +1437,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
{ {
logAi->errorStream() << "Hero " << h->name << " cannot reach " << dst; logAi->errorStream() << "Hero " << h->name << " cannot reach " << dst;
//setGoal(h, INVALID); //setGoal(h, INVALID);
completeGoal (sptr(Goals::VisitTile(int3(-1,-1,-1)).sethero(h))); //TODO: better mechanism to determine goal completeGoal (sptr(Goals::VisitTile(dst).sethero(h))); //TODO: better mechanism to determine goal
cb->recalculatePaths(); cb->recalculatePaths();
throw std::runtime_error("Wrong move order!"); throw std::runtime_error("Wrong move order!");
} }