ソースを参照

Compile fixes, refactoring

DjWarmonger 12 年 前
コミット
b0bdfff117
4 ファイル変更35 行追加62 行削除
  1. 12 0
      AI/VCAI/Goals.cpp
  2. 2 2
      AI/VCAI/Goals.h
  3. 20 60
      AI/VCAI/VCAI.cpp
  4. 1 0
      AI/VCAI/VCAI.h

+ 12 - 0
AI/VCAI/Goals.cpp

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

+ 2 - 2
AI/VCAI/Goals.h

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

+ 20 - 60
AI/VCAI/VCAI.cpp

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

+ 1 - 0
AI/VCAI/VCAI.h

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