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:
parent
0ab7b498f5
commit
cedb3ea82a
@ -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;
|
||||||
|
//}
|
@ -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);
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
|
@ -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>
|
||||||
|
@ -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!");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user