Browse Source

More AI stuff.

Trevor Standley 16 years ago
parent
commit
af1a55e063
4 changed files with 43 additions and 31 deletions
  1. 17 17
      AI/GeniusAI/AIPriorities.cpp
  2. 1 1
      AI/GeniusAI/AIPriorities.h
  3. 23 13
      AI/GeniusAI/CGeniusAI.cpp
  4. 2 0
      AI/GeniusAI/CGeniusAI.h

+ 17 - 17
AI/GeniusAI/AIPriorities.cpp

@@ -13,7 +13,7 @@ Network::Network(vector<unsigned int> whichFeatures)// random network
 }
 Network::Network(istream & input)
 {
-	vector<int> whichFeatures;
+	//vector<int> whichFeatures;
 	int feature;
 	string line;
 	getline(input,line);
@@ -45,27 +45,27 @@ Priorities::Priorities()//random brain
 /*	vector<unsigned int> whichFeatures;//(512);
 	whichFeatures.push_back(16);
 	whichFeatures.push_back(17);
-	networks.push_back(Network(whichFeatures));	//for a friendly hero
-	networks.push_back(Network(whichFeatures));	//for an enemy hero
+	objectNetworks.push_back(Network(whichFeatures));	//for a friendly hero
+	objectNetworks.push_back(Network(whichFeatures));	//for an enemy hero
 
 	whichFeatures.clear();
 	whichFeatures.push_back(16);				//hero's AI value
-	networks.push_back(Network(whichFeatures));	//for school of magic
+	objectNetworks.push_back(Network(whichFeatures));	//for school of magic
 
 	whichFeatures.clear();
 	for(int i = 0; i <=16;i++)
 		whichFeatures.push_back(i);				//hero's AI value is 16
 
-	networks.push_back(Network(whichFeatures));	//for treasure chest
+	objectNetworks.push_back(Network(whichFeatures));	//for treasure chest
 
 	whichFeatures.clear();
 	whichFeatures.push_back(17);
-	networks.push_back(Network(whichFeatures));	//for a friendly town
-	networks.push_back(Network(whichFeatures));	//for an enemy town
+	objectNetworks.push_back(Network(whichFeatures));	//for a friendly town
+	objectNetworks.push_back(Network(whichFeatures));	//for an enemy town
 
 	whichFeatures.clear();
 	whichFeatures.push_back(16);
-	networks.push_back(Network(whichFeatures));	//for learning stone
+	objectNetworks.push_back(Network(whichFeatures));	//for learning stone
 */
 }
 
@@ -76,11 +76,11 @@ Priorities::Priorities(const string & filename)	//read brain from file
 
 	// object_num [list of features]
 	// brain data or "R" for random brain
-	networks.resize(255);
+	objectNetworks.resize(255);
 	int object_num;
 	while(infile>>object_num)
 	{
-		networks[object_num].push_back(Network(infile));
+		objectNetworks[object_num].push_back(Network(infile));
 	}
 }
 
@@ -176,12 +176,12 @@ float Priorities::getValue(const CGeniusAI::AIObjective & obj)
 			{
 				
 				stateFeatures[17] = dynamic_cast<const CGHeroInstance*>(hobj->object)->getTotalStrength();
-				return networks[34][0].feedForward(stateFeatures);
+				return objectNetworks[34][0].feedForward(stateFeatures);
 			}
 			else
 			{
 				stateFeatures[17] = dynamic_cast<const CGHeroInstance*>(hobj->object)->getTotalStrength();
-				return networks[34][1].feedForward(stateFeatures);
+				return objectNetworks[34][1].feedForward(stateFeatures);
 			}
 
 			break;
@@ -189,12 +189,12 @@ float Priorities::getValue(const CGeniusAI::AIObjective & obj)
 			if(dynamic_cast<const CGTownInstance*>(hobj->object)->getOwner()==obj.AI->m_cb->getMyColor())//friendly town
 			{
 				stateFeatures[17] = dynamic_cast<const CGTownInstance*>(hobj->object)->getArmyStrength();
-				return networks[98][0].feedForward(stateFeatures);
+				return objectNetworks[98][0].feedForward(stateFeatures);
 			}
 			else
 			{
 				stateFeatures[17] = dynamic_cast<const CGTownInstance*>(hobj->object)->getArmyStrength();
-				return networks[98][1].feedForward(stateFeatures);
+				return objectNetworks[98][1].feedForward(stateFeatures);
 			}
 
 			break;
@@ -209,14 +209,14 @@ float Priorities::getValue(const CGeniusAI::AIObjective & obj)
 		case 215://quest guard
 			return 0;
 		case 53:	//various mines
-			return networks[53][hobj->object->subID].feedForward(stateFeatures);
+			return objectNetworks[53][hobj->object->subID].feedForward(stateFeatures);
 		case 113://TODO: replace with value of skill for the hero
 			return 0;
 		case 103:case 58://TODO: replace with value of seeing x number of new tiles 
 			return 0;
 		default:
-			if(networks[hobj->object->ID].size()!=0)
-				return networks[hobj->object->ID][0].feedForward(stateFeatures);
+			if(objectNetworks[hobj->object->ID].size()!=0)
+				return objectNetworks[hobj->object->ID][0].feedForward(stateFeatures);
 			cout << "don't know the value of ";
 			switch(obj.type)
 			{

+ 1 - 1
AI/GeniusAI/AIPriorities.h

@@ -32,7 +32,7 @@ public:
 	void fillFeatures(const CGeniusAI::HypotheticalGameState & AI);
 	float getValue(const CGeniusAI::AIObjective & obj);
 	float getCost(vector<int> &resourceCosts,const CGHeroInstance * moved,int distOutOfTheWay);
-	vector<vector<Network> > networks;
+	vector<vector<Network> > objectNetworks;
 };
 
 }

+ 23 - 13
AI/GeniusAI/CGeniusAI.cpp

@@ -82,8 +82,11 @@ void CGeniusAI::HypotheticalGameState::update(CGeniusAI & ai)
 		heroModels.push_back(HeroModel(*i));
 	for(int i = 0; i < oldModels.size();i++)
 		for(int ii = 0; ii < heroModels.size();ii++)
-			if(oldModels[i].finished&&oldModels[i].h->id==heroModels[ii].h->id)
-				heroModels[ii].finished = true;
+			if(oldModels[i].h->subID==heroModels[ii].h->subID)
+			{
+				heroModels[ii].finished = oldModels[i].finished;
+				heroModels[ii].previouslyVisited_pos=oldModels[i].previouslyVisited_pos;
+			}
 	
 	townModels.clear();
 	std::vector < const CGTownInstance *> towns = ai.m_cb->getTownsInfo();	
@@ -359,8 +362,10 @@ void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h
 	if(h.finished) return;
 	for(std::set<AIObjectContainer>::const_iterator i = hgs.knownVisitableObjects.begin(); i != hgs.knownVisitableObjects.end();i++)
 	{
+		if(	h.previouslyVisited_pos==i->o->getSightCenter())
+			continue;
 		//TODO: what would the hero actually visit if he went to that spot
-		//      IE maybe the hero wants to visit a seemingly unguarded enemy town, but there is a hero on top of it.
+		//      maybe the hero wants to visit a seemingly unguarded enemy town, but there is a hero on top of it.
 		//if(i->o->)
 		if(i->o->ID!=HEROI_TYPE)			//unless you are trying to visit a hero
 		{
@@ -371,6 +376,9 @@ void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h
 			if(heroThere)			//it won't work if there is already someone visiting that spot.
 				continue;
 		}
+		if(i->o->id==h.h->id)	//don't visit yourself (should be caught by above)
+			continue;
+		
 		if(i->o->getOwner()!=m_cb->getMyColor())	
 		{
 			int enemyStrength = 0;							//TODO: I feel like the AI shouldn't have access to this information.
@@ -383,7 +391,7 @@ void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h
 				enemyStrength = (dynamic_cast<const CGTownInstance *> (i->o))->getArmyStrength()*1.2;
 			
 			if(enemyStrength*1.2 > h.h->getHeroStrength())  //TODO: ballence these numbers using objective cost formula.
-				continue;
+				continue;									//      it would be nice to do a battle sim
 			if(enemyStrength!=0)tp  = AIObjective::attack;
 		}
 
@@ -393,8 +401,8 @@ void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h
 			continue;
 		if(dynamic_cast<const CGVisitableOPH *> (i->o)&&vstd::contains(dynamic_cast<const CGVisitableOPH *> (i->o)->visitors,h.h->id))//don't visit things that you have already visited OPH
 			continue;
-		if(i->o->id==h.h->id)	//don't visit yourself
-			continue;
+
+
 		
 		if(i->o->ID==88||i->o->ID==89||i->o->ID==90)
 		{
@@ -501,7 +509,6 @@ void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg,HypotheticalGameState & hg
 
 		break;
 	case visit:case attack:
-
 		float bestCost = 9e9;
 		int bestHero = 0;
 		vector<int> resourceCosts;
@@ -533,6 +540,7 @@ void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg,HypotheticalGameState & hg
 		}
 
 		h = whoCanAchieve[bestHero];		//lowest cost hero
+		h->previouslyVisited_pos=object->getSightCenter();
 		//if(dynamic_cast<const CGVisitableOPH *> (object))
 		//	std::cout << h->h->name << " is visiting " << object->hoverName << std::endl;
 		hpos = h->pos;
@@ -543,7 +551,7 @@ void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg,HypotheticalGameState & hg
 
 
 	}
-	if(type == visit||type == finishTurn)
+	if(type == visit||type == finishTurn||type == attack)
 	if(cg.m_cb->getPath(hpos,destination,h->h,path))
 	{
 		path.convert(0);
@@ -793,8 +801,8 @@ CGeniusAI::AIObjective * CGeniusAI::getBestObjective()
 //		return max_element(objectiveQueue.begin(),objectiveQueue.end())->obj;
 	m_priorities->fillFeatures(trueGameState);
 	if(objectiveQueue.empty()) return NULL;
-	sort(objectiveQueue.begin(),objectiveQueue.end());
-	reverse(objectiveQueue.begin(),objectiveQueue.end());
+//	sort(objectiveQueue.begin(),objectiveQueue.end());
+//	reverse(objectiveQueue.begin(),objectiveQueue.end());
 	int num= 1;
 //	for(std::vector<AIObjectivePtrCont> ::iterator i = objectiveQueue.begin(); i < objectiveQueue.end();i++)
 //	{
@@ -808,9 +816,11 @@ CGeniusAI::AIObjective * CGeniusAI::getBestObjective()
 //	cout << "which would you do? (enter 0 for none): ";
 //	cin >> choice;
 	cout << "doing best of " << objectiveQueue.size() << " ";
-	objectiveQueue.front().obj->print();
-	cout << endl;
-
+	CGeniusAI::AIObjective* best = max_element(objectiveQueue.begin(),objectiveQueue.end())->obj;
+	best->print();
+	cout << " value = " << best->getValue() << endl;
+	if(!objectiveQueue.empty())
+		return best;
 	return objectiveQueue.front().obj;
 
 }

+ 2 - 0
AI/GeniusAI/CGeniusAI.h

@@ -50,6 +50,7 @@ private:
 			HeroModel(){}
 			HeroModel(const CGHeroInstance * h);
 			int3 pos;
+			int3 previouslyVisited_pos;
 			int3 interestingPos;
 			bool finished;
 			int remainingMovement;
@@ -86,6 +87,7 @@ private:
 			//flee,
 			dismissUnits,
 			dismissYourself,
+			rearangeTroops,
 			finishTurn,			//done	//uses up remaining motion to get somewhere interesting.
 
 			//town objectives