Browse Source

- Fixed VisitHero goal. Now heroes can exchange armies again.
- AI should not get lazy in endgame.
- Removed unused code.

DjWarmonger 11 years ago
parent
commit
9ec299931d
4 changed files with 28 additions and 35 deletions
  1. 12 6
      AI/VCAI/Fuzzy.cpp
  2. 1 3
      AI/VCAI/Fuzzy.h
  3. 3 2
      AI/VCAI/Goals.cpp
  4. 12 24
      AI/VCAI/VCAI.cpp

+ 12 - 6
AI/VCAI/Fuzzy.cpp

@@ -308,7 +308,7 @@ Goals::TSubgoal FuzzyHelper::chooseSolution (Goals::TGoalVec vec)
 
 	for (auto g : vec)
 	{
-		g->setpriority (g->accept(this));
+		setPriority(g);
 	}
 
 	auto compareGoals = [&](Goals::TSubgoal & lhs, const Goals::TSubgoal & rhs) -> bool
@@ -353,9 +353,10 @@ void FuzzyHelper::initVisitTile()
 	vt.strengthRatio->addTerm (new fl::ShoulderTerm("LOW", 0.9, SAFE_ATTACK_CONSTANT, true));
 	vt.strengthRatio->addTerm (new fl::ShoulderTerm("HIGH", SAFE_ATTACK_CONSTANT, SAFE_ATTACK_CONSTANT * 3, false));
 
-	vt.heroStrength->addTerm (new fl::ShoulderTerm("LOW", 1, 2500, true)); //assumed strength of new hero from tavern
-	vt.heroStrength->addTerm (new fl::TriangularTerm("MEDIUM", 2500, 40000)); //assumed strength of hero able to defeat bank
-	vt.heroStrength->addTerm (new fl::ShoulderTerm("HIGH", 40000, 1e5, false)); //assumed strength of hero able to clear utopia
+	//strength compared to our main hero
+	vt.heroStrength->addTerm (new fl::ShoulderTerm("LOW", 0.01, 0.2, true));
+	vt.heroStrength->addTerm (new fl::TriangularTerm("MEDIUM", 0.1, 0.6));
+	vt.heroStrength->addTerm (new fl::ShoulderTerm("HIGH", 0.5, 0.99, false));
 
 	vt.tileDistance->addTerm (new fl::ShoulderTerm("SMALL", 0, 3.5, true));
 	vt.tileDistance->addTerm (new fl::TriangularTerm("MEDIUM", 3, 10.5));
@@ -416,7 +417,7 @@ float FuzzyHelper::evaluate (Goals::VisitTile & g)
 	try
 	{
 		vt.strengthRatio->setInput (strengthRatio);
-		vt.heroStrength->setInput (g.hero->getTotalStrength());
+		vt.heroStrength->setInput (g.hero->getTotalStrength()/ai->primaryHero()->getTotalStrength());
 		vt.tileDistance->setInput (distance);
 		vt.missionImportance->setInput (missionImportance);
 		vt.movement->setInput(g.hero->movement);
@@ -434,8 +435,9 @@ float FuzzyHelper::evaluate (Goals::VisitTile & g)
 float FuzzyHelper::evaluate (Goals::VisitHero & g)
 {
 	auto obj = cb->getObj(ObjectInstanceID(g.objid)); //we assume for now that these goals are similiar
-	return Goals::VisitTile(obj->pos).sethero(g.hero).setisAbstract(g.isAbstract).accept(this);
 	//TODO: consider direct copy (constructor?)
+	g.setpriority(Goals::VisitTile(obj->visitablePos()).sethero(g.hero).setisAbstract(g.isAbstract).accept(this));
+	return g.priority;	
 }
 float FuzzyHelper::evaluate (Goals::BuildThis & g)
 {
@@ -462,3 +464,7 @@ float FuzzyHelper::evaluate (Goals::AbstractGoal & g)
 	logAi->warnStream() << boost::format("Cannot evaluate goal %s") % g.name();
 	return g.priority;
 }
+void FuzzyHelper::setPriority (Goals::TSubgoal & g)
+{
+	g->setpriority(g->accept(this)); //this enforces returned value is set
+}

+ 1 - 3
AI/VCAI/Fuzzy.h

@@ -14,9 +14,6 @@
 
 class VCAI;
 class CArmedInstance;
-//class TSubgoal;
-//class TGoalVec;
-//class AbstractGoal;
 
 class FuzzyHelper
 {
@@ -71,6 +68,7 @@ public:
 	float evaluate (Goals::Build & g);
 	float evaluate (Goals::Invalid & g);
 	float evaluate (Goals::AbstractGoal & g);
+	void setPriority (Goals::TSubgoal & g);
 
 	ui64 estimateBankDanger (int ID);
 	float getTacticalAdvantage (const CArmedInstance *we, const CArmedInstance *enemy); //returns factor how many times enemy is stronger than us

+ 3 - 2
AI/VCAI/Goals.cpp

@@ -304,8 +304,9 @@ TSubgoal VisitHero::whatToDoToAchieve()
 			logAi->errorStream() << "Hero " << hero.name << " tries to visit himself.";
 		else
 		{
-			settile(pos).setisElementar(true);
-			return sptr (*this);
+			//can't use VISIT_TILE here as tile appears blocked by target hero
+			//FIXME: elementar goal should not be abstract
+			return sptr (Goals::VisitHero(objid).sethero(hero).settile(pos).setisElementar(true));
 		}
 	}
 	return sptr (Goals::Invalid());

+ 12 - 24
AI/VCAI/VCAI.cpp

@@ -700,28 +700,16 @@ void VCAI::makeTurnInternal()
 		striveToGoal(sptr(Goals::Win()));
 
 		//finally, continue our abstract long-term goals
-
-		//int i = 100;
 		int oldMovement = 0;
 		int newMovement = 0;
 		while (true)
 		{
-			//if (!i)
-			//{
-			//	logAi->warnStream() << "Locked heroes: exhaustive decomposition failed!";
-			//	break;
-			//	/*If we are here, it can mean two things:
-			//	1. W are striving to impossible goal (bug!)
-			//	2. Our strategy seems perfect and no move can bring improvement
-			//	*/
-			//}
-			//--i;
 			oldMovement = newMovement; //remember old value
 			newMovement = 0;
 			std::vector<std::pair<HeroPtr, Goals::TSubgoal> > safeCopy;
 			for (auto mission : lockedHeroes)
 			{
-				mission.second->accept(fh); //re-evaluate
+				fh->setPriority (mission.second); //re-evaluate
 				if (canAct(mission.first))
 				{
 					newMovement += mission.first->movement;
@@ -1589,15 +1577,8 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
 
 			int3 endpos = path.nodes[i-1].coord;
 			if(endpos == h->visitablePos())
-			//if (endpos == h->pos)
 				continue;
-// 			if(i > 1)
-// 			{
-// 				int3 afterEndPos = path.nodes[i-2].coord;
-// 				if(afterEndPos.z != endpos.z)
-//
-// 			}
-            //logAi->debugStream() << "Moving " << h->name << " from " << h->getPosition() << " to " << endpos;
+
 			cb->moveHero(*h, CGHeroInstance::convertPosition(endpos, true));
 			waitTillFree(); //movement may cause battle or blocking dialog
 			boost::this_thread::interruption_point();
@@ -1672,11 +1653,18 @@ void VCAI::tryRealize(Goals::VisitTile & g)
 void VCAI::tryRealize(Goals::VisitHero & g)
 {
 	if(!g.hero->movement)
-		throw cannotFulfillGoalException("Cannot visit tile: hero is out of MPs!");
-	if (ai->moveHeroToTile(g.tile, g.hero.get()))
+		throw cannotFulfillGoalException("Cannot visit target hero: hero is out of MPs!");
+
+	const CGObjectInstance * obj = cb->getObj(ObjectInstanceID(g.objid));
+	if (obj)
 	{
-		throw goalFulfilledException (sptr(g));
+		if (ai->moveHeroToTile(obj->visitablePos(), g.hero.get()))
+		{
+			throw goalFulfilledException (sptr(g));
+		}
 	}
+	else
+		throw cannotFulfillGoalException("Cannot visit hero: object not found!");
 }
 
 void VCAI::tryRealize(Goals::BuildThis & g)