mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
Compile fixes, refactoring
This commit is contained in:
parent
27a30b5ff9
commit
b0bdfff117
@ -851,3 +851,15 @@ void CGoal<T>::accept (VCAI * ai)
|
||||
{
|
||||
ai->tryRealize(static_cast<T&>(*this)); //casting enforces template instantiation
|
||||
}
|
||||
|
||||
//TODO: find out why the following are not generated automatically on MVS?
|
||||
void CGoal<Win>::accept (VCAI * ai)
|
||||
{
|
||||
ai->tryRealize(static_cast<Win&>(*this));
|
||||
}
|
||||
|
||||
void CGoal<Build>::accept (VCAI * ai)
|
||||
{
|
||||
ai->tryRealize(static_cast<Build&>(*this));
|
||||
}
|
||||
|
||||
|
@ -100,10 +100,11 @@ public:
|
||||
static TSubgoal tryRecruitHero();
|
||||
|
||||
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 bool operator== (AbstractGoal &g) //TODO: virtualize - comparison returns true only for same subclasses
|
||||
virtual bool operator== (AbstractGoal &g)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -195,7 +196,6 @@ class Build : public CGoal<Build>
|
||||
public:
|
||||
Build() : CGoal (Goals::BUILD){};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
void accept (const VCAI *);
|
||||
};
|
||||
class Explore : public CGoal<Explore>
|
||||
{
|
||||
|
@ -1703,28 +1703,42 @@ void VCAI::striveToGoal(Goals::TSubgoal ultimateGoal)
|
||||
if (ultimateGoal->invalid())
|
||||
return;
|
||||
|
||||
//we are looking for abstract goals
|
||||
auto abstractGoal = striveToGoalInternal (ultimateGoal, false);
|
||||
|
||||
if (abstractGoal->invalid())
|
||||
return;
|
||||
|
||||
//we received abstratc goal, need to find concrete goals
|
||||
striveToGoalInternal (abstractGoal, true);
|
||||
|
||||
//TODO: save abstract goals not related to hero
|
||||
}
|
||||
|
||||
Goals::TSubgoal VCAI::striveToGoalInternal(Goals::TSubgoal ultimateGoal, bool onlyAbstract)
|
||||
{
|
||||
Goals::TSubgoal abstractGoal = sptr(Goals::Invalid());
|
||||
|
||||
while(1)
|
||||
{
|
||||
Goals::TSubgoal goal = ultimateGoal; //FIXME: preserve subclass of goal
|
||||
Goals::TSubgoal goal = ultimateGoal;
|
||||
logAi->debugStream() << boost::format("Striving to goal of type %s") % ultimateGoal->name();
|
||||
int maxGoals = 100; //preventing deadlock for mutually dependent goals
|
||||
//FIXME: do not try to realize goal when loop didn't suceed
|
||||
while(!goal->isElementar && !goal->isAbstract && maxGoals)
|
||||
while(!goal->isElementar && maxGoals && (onlyAbstract || !goal->isAbstract))
|
||||
{
|
||||
logAi->debugStream() << boost::format("Considering goal %s") % goal->name();
|
||||
try
|
||||
{
|
||||
boost::this_thread::interruption_point();
|
||||
goal = goal->whatToDoToAchieve(); //FIXME: why it calls always base class?
|
||||
goal = goal->whatToDoToAchieve();
|
||||
--maxGoals;
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
logAi->debugStream() << boost::format("Goal %s decomposition failed: %s") % goal->name() % e.what();
|
||||
//setGoal (goal.hero, INVALID); //test: if we don't know how to realize goal, we should abandon it for now
|
||||
return;
|
||||
return sptr(Goals::Invalid());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1770,7 +1784,7 @@ void VCAI::striveToGoal(Goals::TSubgoal ultimateGoal)
|
||||
{
|
||||
completeGoal (goal);
|
||||
if (fulfillsGoal (goal, ultimateGoal) || maxGoals > 98) //completed goal was main goal //TODO: find better condition
|
||||
return;
|
||||
return sptr(Goals::Invalid());
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
@ -1779,61 +1793,7 @@ void VCAI::striveToGoal(Goals::TSubgoal ultimateGoal)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: save abstract goals not related to hero
|
||||
//TODO: refactor, duplicated code
|
||||
if (!abstractGoal->invalid()) //try to realize our one goal
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
std::shared_ptr<Goals::AbstractGoal> goal(abstractGoal);
|
||||
goal->setisAbstract(false);
|
||||
int maxGoals = 50;
|
||||
while (!goal->isElementar && maxGoals) //find elementar goal and fulfill it
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::this_thread::interruption_point();
|
||||
goal = goal->whatToDoToAchieve();
|
||||
--maxGoals;
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
logAi->debugStream() << boost::format("Goal %s decomposition failed: %s") % goal->name() % e.what();
|
||||
//setGoal (goal.hero, INVALID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
boost::this_thread::interruption_point();
|
||||
if (!maxGoals)
|
||||
{
|
||||
std::runtime_error e("Too many subgoals, don't know what to do");
|
||||
throw (e);
|
||||
}
|
||||
goal->accept(this);
|
||||
boost::this_thread::interruption_point();
|
||||
}
|
||||
catch(boost::thread_interrupted &e)
|
||||
{
|
||||
logAi->debugStream() << boost::format("Player %d: Making turn thread received an interruption!") % playerID;
|
||||
throw; //rethrow, we want to truly end this thread
|
||||
}
|
||||
catch(goalFulfilledException &e)
|
||||
{
|
||||
completeGoal (goal); //FIXME: deduce that we have realized GET_OBJ goal
|
||||
if (fulfillsGoal (goal, abstractGoal) || maxGoals > 98) //completed goal was main goal
|
||||
return;
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
logAi->debugStream() << boost::format("Failed to realize subgoal of type %s (greater goal type was %s), I will stop.") % goal->name() % ultimateGoal->name();
|
||||
logAi->debugStream() << boost::format("The error message was: %s") % e.what();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return abstractGoal;
|
||||
}
|
||||
|
||||
void VCAI::striveToQuest (const QuestInfo &q)
|
||||
|
@ -233,6 +233,7 @@ public:
|
||||
|
||||
void buildArmyIn(const CGTownInstance * t);
|
||||
void striveToGoal(Goals::TSubgoal ultimateGoal);
|
||||
Goals::TSubgoal striveToGoalInternal(Goals::TSubgoal ultimateGoal, bool onlyAbstract);
|
||||
void endTurn();
|
||||
void wander(HeroPtr h);
|
||||
void setGoal(HeroPtr h, Goals::TSubgoal goal);
|
||||
|
Loading…
Reference in New Issue
Block a user