1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-09-16 09:26:28 +02:00

More AI stuff.

This commit is contained in:
Trevor Standley
2009-08-19 10:18:14 +00:00
parent d38c8e5ada
commit af1a55e063
4 changed files with 43 additions and 31 deletions

View File

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

View File

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

View File

@@ -82,8 +82,11 @@ void CGeniusAI::HypotheticalGameState::update(CGeniusAI & ai)
heroModels.push_back(HeroModel(*i)); heroModels.push_back(HeroModel(*i));
for(int i = 0; i < oldModels.size();i++) for(int i = 0; i < oldModels.size();i++)
for(int ii = 0; ii < heroModels.size();ii++) for(int ii = 0; ii < heroModels.size();ii++)
if(oldModels[i].finished&&oldModels[i].h->id==heroModels[ii].h->id) if(oldModels[i].h->subID==heroModels[ii].h->subID)
heroModels[ii].finished = true; {
heroModels[ii].finished = oldModels[i].finished;
heroModels[ii].previouslyVisited_pos=oldModels[i].previouslyVisited_pos;
}
townModels.clear(); townModels.clear();
std::vector < const CGTownInstance *> towns = ai.m_cb->getTownsInfo(); std::vector < const CGTownInstance *> towns = ai.m_cb->getTownsInfo();
@@ -359,8 +362,10 @@ void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h
if(h.finished) return; if(h.finished) return;
for(std::set<AIObjectContainer>::const_iterator i = hgs.knownVisitableObjects.begin(); i != hgs.knownVisitableObjects.end();i++) 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 //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->)
if(i->o->ID!=HEROI_TYPE) //unless you are trying to visit a hero 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. if(heroThere) //it won't work if there is already someone visiting that spot.
continue; 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()) if(i->o->getOwner()!=m_cb->getMyColor())
{ {
int enemyStrength = 0; //TODO: I feel like the AI shouldn't have access to this information. 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; 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. 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; if(enemyStrength!=0)tp = AIObjective::attack;
} }
@@ -393,8 +401,8 @@ void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h
continue; 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 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; 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) 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; break;
case visit:case attack: case visit:case attack:
float bestCost = 9e9; float bestCost = 9e9;
int bestHero = 0; int bestHero = 0;
vector<int> resourceCosts; vector<int> resourceCosts;
@@ -533,6 +540,7 @@ void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg,HypotheticalGameState & hg
} }
h = whoCanAchieve[bestHero]; //lowest cost hero h = whoCanAchieve[bestHero]; //lowest cost hero
h->previouslyVisited_pos=object->getSightCenter();
//if(dynamic_cast<const CGVisitableOPH *> (object)) //if(dynamic_cast<const CGVisitableOPH *> (object))
// std::cout << h->h->name << " is visiting " << object->hoverName << std::endl; // std::cout << h->h->name << " is visiting " << object->hoverName << std::endl;
hpos = h->pos; 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)) if(cg.m_cb->getPath(hpos,destination,h->h,path))
{ {
path.convert(0); path.convert(0);
@@ -793,8 +801,8 @@ CGeniusAI::AIObjective * CGeniusAI::getBestObjective()
// return max_element(objectiveQueue.begin(),objectiveQueue.end())->obj; // return max_element(objectiveQueue.begin(),objectiveQueue.end())->obj;
m_priorities->fillFeatures(trueGameState); m_priorities->fillFeatures(trueGameState);
if(objectiveQueue.empty()) return NULL; if(objectiveQueue.empty()) return NULL;
sort(objectiveQueue.begin(),objectiveQueue.end()); // sort(objectiveQueue.begin(),objectiveQueue.end());
reverse(objectiveQueue.begin(),objectiveQueue.end()); // reverse(objectiveQueue.begin(),objectiveQueue.end());
int num= 1; int num= 1;
// for(std::vector<AIObjectivePtrCont> ::iterator i = objectiveQueue.begin(); i < objectiveQueue.end();i++) // 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): "; // cout << "which would you do? (enter 0 for none): ";
// cin >> choice; // cin >> choice;
cout << "doing best of " << objectiveQueue.size() << " "; cout << "doing best of " << objectiveQueue.size() << " ";
objectiveQueue.front().obj->print(); CGeniusAI::AIObjective* best = max_element(objectiveQueue.begin(),objectiveQueue.end())->obj;
cout << endl; best->print();
cout << " value = " << best->getValue() << endl;
if(!objectiveQueue.empty())
return best;
return objectiveQueue.front().obj; return objectiveQueue.front().obj;
} }

View File

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