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:
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user