1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-05 15:05:40 +02:00

Various fixes. Temporarily replaced neural network's output with random number.

This commit is contained in:
Trevor Standley 2009-08-21 18:18:52 +00:00
parent ac7c7a3d23
commit f4743d2fc6
5 changed files with 800 additions and 126 deletions

View File

@ -1,52 +1,736 @@
34 16 17 o 34 16 17
R R
34 16 17 o 34 16 17
R R
47 16 o 47 16
R R
101 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 24 o 101 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 24
R R
98 16 17 o 98 16 17
R R
98 16 17 o 98 16 17
R R
100 16 o 100 16
R R
38 16 o 38 16
R R
61 16 o 61 16
R R
53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 o 53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R R
53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 o 53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R R
53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 o 53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R R
53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 o 53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R R
53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 o 53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R R
53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 o 53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R R
53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 o 53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R R
53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 o 53 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R R
28 16 o 28 16
R R
81 16 o 81 16
R R
83 25 o 83 25
R R
31 16 o 31 16
R R
57 24 o 57 24
R R
23 16 o 23 16
R R
102 16 o 102 16
R R
37 24 o 37 24
R R
51 16 o 51 16
R
t 0 0 25
R
t 0 1 25
R
t 0 2 25
R
t 0 3 25
R
t 0 4 25
R
t 0 5 25
R
t 0 6 25
R
t 0 7 25
R
t 0 8 25
R
t 0 9 25
R
t 0 10 25
R
t 0 11 25
R
t 0 12 25
R
t 0 13 25
R
t 0 14 25
R
t 0 15 25
R
t 0 16 25
R
t 0 17 25
R
t 0 18 25
R
t 0 19 25
R
t 0 20 25
R
t 0 21 25
R
t 0 22 25
R
t 0 23 25
R
t 0 30 25
R
t 0 31 25
R
t 0 32 25
R
t 0 33 25
R
t 0 34 25
R
t 0 35 25
R
t 0 36 25
R
t 0 37 25
R
t 0 38 25
R
t 0 39 25
R
t 0 40 25
R
t 0 41 25
R
t 0 42 25
R
t 0 43 25
R
t 1 0 25
R
t 1 1 25
R
t 1 2 25
R
t 1 3 25
R
t 1 4 25
R
t 1 5 25
R
t 1 6 25
R
t 1 7 25
R
t 1 8 25
R
t 1 9 25
R
t 1 10 25
R
t 1 11 25
R
t 1 12 25
R
t 1 13 25
R
t 1 14 25
R
t 1 15 25
R
t 1 16 25
R
t 1 17 25
R
t 1 18 25
R
t 1 19 25
R
t 1 20 25
R
t 1 21 25
R
t 1 22 25
R
t 1 23 25
R
t 1 30 25
R
t 1 31 25
R
t 1 32 25
R
t 1 33 25
R
t 1 34 25
R
t 1 35 25
R
t 1 36 25
R
t 1 37 25
R
t 1 38 25
R
t 1 39 25
R
t 1 40 25
R
t 1 41 25
R
t 1 42 25
R
t 1 43 25
R
t 2 0 25
R
t 2 1 25
R
t 2 2 25
R
t 2 3 25
R
t 2 4 25
R
t 2 5 25
R
t 2 6 25
R
t 2 7 25
R
t 2 8 25
R
t 2 9 25
R
t 2 10 25
R
t 2 11 25
R
t 2 12 25
R
t 2 13 25
R
t 2 14 25
R
t 2 15 25
R
t 2 16 25
R
t 2 17 25
R
t 2 18 25
R
t 2 19 25
R
t 2 20 25
R
t 2 21 25
R
t 2 22 25
R
t 2 23 25
R
t 2 30 25
R
t 2 31 25
R
t 2 32 25
R
t 2 33 25
R
t 2 34 25
R
t 2 35 25
R
t 2 36 25
R
t 2 37 25
R
t 2 38 25
R
t 2 39 25
R
t 2 40 25
R
t 2 41 25
R
t 2 42 25
R
t 2 43 25
R
t 3 0 25
R
t 3 1 25
R
t 3 2 25
R
t 3 3 25
R
t 3 4 25
R
t 3 5 25
R
t 3 6 25
R
t 3 7 25
R
t 3 8 25
R
t 3 9 25
R
t 3 10 25
R
t 3 11 25
R
t 3 12 25
R
t 3 13 25
R
t 3 14 25
R
t 3 15 25
R
t 3 16 25
R
t 3 17 25
R
t 3 18 25
R
t 3 19 25
R
t 3 20 25
R
t 3 21 25
R
t 3 22 25
R
t 3 23 25
R
t 3 30 25
R
t 3 31 25
R
t 3 32 25
R
t 3 33 25
R
t 3 34 25
R
t 3 35 25
R
t 3 36 25
R
t 3 37 25
R
t 3 38 25
R
t 3 39 25
R
t 3 40 25
R
t 3 41 25
R
t 3 42 25
R
t 3 43 25
R
t 4 0 25
R
t 4 1 25
R
t 4 2 25
R
t 4 3 25
R
t 4 4 25
R
t 4 5 25
R
t 4 6 25
R
t 4 7 25
R
t 4 8 25
R
t 4 9 25
R
t 4 10 25
R
t 4 11 25
R
t 4 12 25
R
t 4 13 25
R
t 4 14 25
R
t 4 15 25
R
t 4 16 25
R
t 4 17 25
R
t 4 18 25
R
t 4 19 25
R
t 4 20 25
R
t 4 21 25
R
t 4 22 25
R
t 4 23 25
R
t 4 30 25
R
t 4 31 25
R
t 4 32 25
R
t 4 33 25
R
t 4 34 25
R
t 4 35 25
R
t 4 36 25
R
t 4 37 25
R
t 4 38 25
R
t 4 39 25
R
t 4 40 25
R
t 4 41 25
R
t 4 42 25
R
t 4 43 25
R
t 5 0 25
R
t 5 1 25
R
t 5 2 25
R
t 5 3 25
R
t 5 4 25
R
t 5 5 25
R
t 5 6 25
R
t 5 7 25
R
t 5 8 25
R
t 5 9 25
R
t 5 10 25
R
t 5 11 25
R
t 5 12 25
R
t 5 13 25
R
t 5 14 25
R
t 5 15 25
R
t 5 16 25
R
t 5 17 25
R
t 5 18 25
R
t 5 19 25
R
t 5 20 25
R
t 5 21 25
R
t 5 22 25
R
t 5 23 25
R
t 5 30 25
R
t 5 31 25
R
t 5 32 25
R
t 5 33 25
R
t 5 34 25
R
t 5 35 25
R
t 5 36 25
R
t 5 37 25
R
t 5 38 25
R
t 5 39 25
R
t 5 40 25
R
t 5 41 25
R
t 5 42 25
R
t 5 43 25
R
t 6 0 25
R
t 6 1 25
R
t 6 2 25
R
t 6 3 25
R
t 6 4 25
R
t 6 5 25
R
t 6 6 25
R
t 6 7 25
R
t 6 8 25
R
t 6 9 25
R
t 6 10 25
R
t 6 11 25
R
t 6 12 25
R
t 6 13 25
R
t 6 14 25
R
t 6 15 25
R
t 6 16 25
R
t 6 17 25
R
t 6 18 25
R
t 6 19 25
R
t 6 20 25
R
t 6 21 25
R
t 6 22 25
R
t 6 23 25
R
t 6 30 25
R
t 6 31 25
R
t 6 32 25
R
t 6 33 25
R
t 6 34 25
R
t 6 35 25
R
t 6 36 25
R
t 6 37 25
R
t 6 38 25
R
t 6 39 25
R
t 6 40 25
R
t 6 41 25
R
t 6 42 25
R
t 6 43 25
R
t 7 0 25
R
t 7 1 25
R
t 7 2 25
R
t 7 3 25
R
t 7 4 25
R
t 7 5 25
R
t 7 6 25
R
t 7 7 25
R
t 7 8 25
R
t 7 9 25
R
t 7 10 25
R
t 7 11 25
R
t 7 12 25
R
t 7 13 25
R
t 7 14 25
R
t 7 15 25
R
t 7 16 25
R
t 7 17 25
R
t 7 18 25
R
t 7 19 25
R
t 7 20 25
R
t 7 21 25
R
t 7 22 25
R
t 7 23 25
R
t 7 30 25
R
t 7 31 25
R
t 7 32 25
R
t 7 33 25
R
t 7 34 25
R
t 7 35 25
R
t 7 36 25
R
t 7 37 25
R
t 7 38 25
R
t 7 39 25
R
t 7 40 25
R
t 7 41 25
R
t 7 42 25
R
t 7 43 25
R
t 8 0 25
R
t 8 1 25
R
t 8 2 25
R
t 8 3 25
R
t 8 4 25
R
t 8 5 25
R
t 8 6 25
R
t 8 7 25
R
t 8 8 25
R
t 8 9 25
R
t 8 10 25
R
t 8 11 25
R
t 8 12 25
R
t 8 13 25
R
t 8 14 25
R
t 8 15 25
R
t 8 16 25
R
t 8 17 25
R
t 8 18 25
R
t 8 19 25
R
t 8 20 25
R
t 8 21 25
R
t 8 22 25
R
t 8 23 25
R
t 8 30 25
R
t 8 31 25
R
t 8 32 25
R
t 8 33 25
R
t 8 34 25
R
t 8 35 25
R
t 8 36 25
R
t 8 37 25
R
t 8 38 25
R
t 8 39 25
R
t 8 40 25
R
t 8 41 25
R
t 8 42 25
R
t 8 43 25
R R

View File

@ -28,6 +28,7 @@ Network::Network(istream & input)
float Network::feedForward(const vector<float> & stateFeatures) float Network::feedForward(const vector<float> & stateFeatures)
{ {
return (rand()%1000)/800.0;
double * input = new double[whichFeatures.size()]; double * input = new double[whichFeatures.size()];
for(int i = 0; i < whichFeatures.size();i++) for(int i = 0; i < whichFeatures.size();i++)
input[i]=stateFeatures[whichFeatures[i]]; input[i]=stateFeatures[whichFeatures[i]];
@ -38,37 +39,6 @@ float Network::feedForward(const vector<float> & stateFeatures)
return ans; return ans;
} }
Priorities::Priorities()//random brain
:numSpecialFeatures(8)
{
/* vector<unsigned int> whichFeatures;//(512);
whichFeatures.push_back(16);
whichFeatures.push_back(17);
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
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
objectNetworks.push_back(Network(whichFeatures)); //for treasure chest
whichFeatures.clear();
whichFeatures.push_back(17);
objectNetworks.push_back(Network(whichFeatures)); //for a friendly town
objectNetworks.push_back(Network(whichFeatures)); //for an enemy town
whichFeatures.clear();
whichFeatures.push_back(16);
objectNetworks.push_back(Network(whichFeatures)); //for learning stone
*/
}
Priorities::Priorities(const string & filename) //read brain from file Priorities::Priorities(const string & filename) //read brain from file
:numSpecialFeatures(8) :numSpecialFeatures(8)
{ {
@ -77,10 +47,26 @@ 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
objectNetworks.resize(255); objectNetworks.resize(255);
buildingNetworks.resize(9);
char type;
int object_num; int object_num;
while(infile>>object_num) int town_num;
int building_num;
while(infile>>type)
{ {
objectNetworks[object_num].push_back(Network(infile)); switch(type)
{
case 'o'://map object
infile >> object_num;
objectNetworks[object_num].push_back(Network(infile));
break;
case 't'://town building
infile >> town_num >> building_num;
buildingNetworks[town_num][building_num]=Network(infile);
break;
}
} }
} }
@ -116,13 +102,15 @@ float Priorities::getCost(vector<int> &resourceCosts,const CGHeroInstance * move
float Priorities::getValue(const CGeniusAI::AIObjective & obj) float Priorities::getValue(const CGeniusAI::AIObjective & obj)
{ //resource { //resource
vector<int> resourceAmounts(8,0); vector<int> resourceAmounts(8,0);
int amount; int amount;
if(obj.type==CGeniusAI::AIObjective::finishTurn) //TODO: replace with value of visiting that object divided by days till completed if(obj.type==CGeniusAI::AIObjective::finishTurn) //TODO: replace with value of visiting that object divided by days till completed
return .0001; //small nonzero return .0001; //small nonzero
float a; float a;
if(obj.type==CGeniusAI::AIObjective::attack)
return 100;
if(dynamic_cast<const CGeniusAI::HeroObjective* >(&obj)) if(dynamic_cast<const CGeniusAI::HeroObjective* >(&obj))
{ {
const CGeniusAI::HeroObjective* hobj = dynamic_cast<const CGeniusAI::HeroObjective* >(&obj); const CGeniusAI::HeroObjective* hobj = dynamic_cast<const CGeniusAI::HeroObjective* >(&obj);
@ -133,7 +121,7 @@ float Priorities::getValue(const CGeniusAI::AIObjective & obj)
{ {
case 5: //artifact //TODO: return value of each artifact case 5: //artifact //TODO: return value of each artifact
return 0; return 0;
case 79: case 79://resources on the ground
switch(hobj->object->subID) switch(hobj->object->subID)
{ {
case 6: case 6:
@ -235,7 +223,19 @@ float Priorities::getValue(const CGeniusAI::AIObjective & obj)
} }
else //town objective else //town objective
{ {
if(obj.type == CGeniusAI::AIObjective::buildBuilding)
{
const CGeniusAI::TownObjective* tnObj = dynamic_cast<const CGeniusAI::TownObjective* >(&obj);
if(buildingNetworks[tnObj->whichTown->t->subID].find(tnObj->which)!=buildingNetworks[tnObj->whichTown->t->subID].end())
return buildingNetworks[tnObj->whichTown->t->subID][tnObj->which].feedForward(stateFeatures);
else
{
cout << "don't know the value of ";
obj.print();
cout << endl;
}
}
} }

View File

@ -22,7 +22,6 @@ public:
class Priorities class Priorities
{ {
public: public:
Priorities(); //random brain
Priorities(const string & filename); //read brain from file Priorities(const string & filename); //read brain from file
@ -33,6 +32,7 @@ public:
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> > objectNetworks; vector<vector<Network> > objectNetworks;
vector<map<int,Network> > buildingNetworks;
}; };
} }

View File

@ -73,7 +73,7 @@ CGeniusAI::HypotheticalGameState::HypotheticalGameState(CGeniusAI & ai)
void CGeniusAI::HypotheticalGameState::update(CGeniusAI & ai) void CGeniusAI::HypotheticalGameState::update(CGeniusAI & ai)
{ {
AI = &ai; AI = &ai;
// knownVisitableObjects = ai.knownVisitableObjects; knownVisitableObjects = ai.knownVisitableObjects;
std::vector<HeroModel> oldModels = heroModels; std::vector<HeroModel> oldModels = heroModels;
heroModels.clear(); heroModels.clear();
@ -122,22 +122,23 @@ float CGeniusAI::HeroObjective::getValue() const
resourceCosts[6]+=1000; resourceCosts[6]+=1000;
float bestCost = 9e9; float bestCost = 9e9;
HypotheticalGameState::HeroModel * bestHero = NULL;
if(type !=AIObjective::finishTurn) if(type !=AIObjective::finishTurn)
{ {
for(int i = 0; i < whoCanAchieve.size();i++) for(int i = 0; i < whoCanAchieve.size();i++)
{ {
int distOutOfTheWay = 0; int distOutOfTheWay = 0;
CPath path; CPath path3;
//from hero to object //from hero to object
if(AI->m_cb->getPath(whoCanAchieve[i]->pos,pos,whoCanAchieve[i]->h,path)) if(AI->m_cb->getPath(whoCanAchieve[i]->pos,pos,whoCanAchieve[i]->h,path3))
distOutOfTheWay+=path.nodes[0].dist; distOutOfTheWay+=path3.nodes[0].dist;
//from object to goal //from object to goal
if(AI->m_cb->getPath(pos,whoCanAchieve[i]->interestingPos,whoCanAchieve[i]->h,path)) if(AI->m_cb->getPath(pos,whoCanAchieve[i]->interestingPos,whoCanAchieve[i]->h,path3))
{ {
distOutOfTheWay+=path.nodes[0].dist; distOutOfTheWay+=path3.nodes[0].dist;
//from hero directly to goal //from hero directly to goal
if(AI->m_cb->getPath(whoCanAchieve[i]->pos,whoCanAchieve[i]->interestingPos,whoCanAchieve[i]->h,path)) if(AI->m_cb->getPath(whoCanAchieve[i]->pos,whoCanAchieve[i]->interestingPos,whoCanAchieve[i]->h,path3))
distOutOfTheWay-=path.nodes[0].dist; distOutOfTheWay-=path3.nodes[0].dist;
} }
@ -145,12 +146,20 @@ float CGeniusAI::HeroObjective::getValue() const
float cost = AI->m_priorities->getCost(resourceCosts,whoCanAchieve[i]->h,distOutOfTheWay); float cost = AI->m_priorities->getCost(resourceCosts,whoCanAchieve[i]->h,distOutOfTheWay);
if(cost < bestCost) if(cost < bestCost)
{
bestCost = cost; bestCost = cost;
bestHero = whoCanAchieve[i];
}
} }
} }
else bestCost = 0; else bestCost = 0;
//if(bestCost < 10000) cout << "best cost = " << bestCost << endl; if(bestHero)
{
whoCanAchieve.clear();
whoCanAchieve.push_back(bestHero);
}
_value = AI->m_priorities->getValue(*this); _value = AI->m_priorities->getValue(*this);
_cost=bestCost; _cost=bestCost;
return _value-_cost; return _value-_cost;
@ -178,6 +187,7 @@ void CGeniusAI::HeroObjective::print() const
break; break;
case attack: case attack:
cout << "attack " << object->hoverName; cout << "attack " << object->hoverName;
break;
case finishTurn: case finishTurn:
cout << "finish turn"; cout << "finish turn";
} }
@ -230,8 +240,9 @@ float CGeniusAI::TownObjective::getValue() const
ID = whichTown->creaturesInGarrison.slots[which].first; ID = whichTown->creaturesInGarrison.slots[which].first;
howMany = whichTown->creaturesInGarrison.slots[which].second; howMany = whichTown->creaturesInGarrison.slots[which].second;
newID = ui.newID.back(); newID = ui.newID.back();
for(std::set<std::pair<int,int> >::iterator i = ui.cost[which].begin();i!=ui.cost[which].end();i++) int upgrade_serial = ui.newID.size()-1;
resourceCosts[i->first] = i->second*howMany; for (std::set<std::pair<int,int> >::iterator j=ui.cost[upgrade_serial].begin(); j!=ui.cost[upgrade_serial].end(); j++)
resourceCosts[j->first] = j->second*howMany;
break; break;
@ -362,6 +373,7 @@ 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++)
{ {
tp = AIObjective::visit;
if( h.previouslyVisited_pos==i->o->getSightCenter()) if( h.previouslyVisited_pos==i->o->getSightCenter())
continue; 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
@ -376,9 +388,14 @@ 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==HEROI_TYPE&&i->o->getOwner()==m_cb->getMyColor())//visiting friendly heroes not yet supported
continue;
if(i->o->id==h.h->id) //don't visit yourself (should be caught by above) if(i->o->id==h.h->id) //don't visit yourself (should be caught by above)
continue; continue;
if(i->o->ID==53&&i->o->getOwner()==m_cb->getMyColor())//don't visit a mine if you own, there's almost no point(maybe to leave guards or because the hero's trapped).
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.
@ -386,17 +403,16 @@ void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h
if(dynamic_cast<const CArmedInstance *> (i->o)) if(dynamic_cast<const CArmedInstance *> (i->o))
enemyStrength = (dynamic_cast<const CArmedInstance *> (i->o))->getArmyStrength();//TODO: should be virtual maybe, Army strength should be comparable across objects enemyStrength = (dynamic_cast<const CArmedInstance *> (i->o))->getArmyStrength();//TODO: should be virtual maybe, Army strength should be comparable across objects
if(dynamic_cast<const CGHeroInstance *> (i->o)) if(dynamic_cast<const CGHeroInstance *> (i->o))
enemyStrength = (dynamic_cast<const CGHeroInstance *> (i->o))->getHeroStrength(); enemyStrength = (dynamic_cast<const CGHeroInstance *> (i->o))->getTotalStrength();
if(dynamic_cast<const CGTownInstance *> (i->o)) if(dynamic_cast<const CGTownInstance *> (i->o))
enemyStrength = (dynamic_cast<const CGTownInstance *> (i->o))->getArmyStrength()*1.2; enemyStrength = (dynamic_cast<const CGTownInstance *> (i->o))->getArmyStrength()*1.2;
float heroStrength = h.h->getTotalStrength();
if(enemyStrength*1.2 > h.h->getHeroStrength()) //TODO: ballence these numbers using objective cost formula. if(enemyStrength*2.5 > heroStrength) //TODO: ballence these numbers using objective cost formula.
continue; // it would be nice to do a battle sim continue; // it would be nice to do a battle sim
if(enemyStrength!=0)tp = AIObjective::attack; if(enemyStrength>0)tp = AIObjective::attack;
} }
if(i->o->ID==53&&i->o->getOwner()==m_cb->getMyColor())//don't visit a mine if you own, there's almost no point(maybe to leave guards or because the hero's trapped).
continue;
if(dynamic_cast<const CGVisitableOPW *> (i->o)&&dynamic_cast<const CGVisitableOPW *> (i->o)->visited)//don't visit things that have already been visited this week. if(dynamic_cast<const CGVisitableOPW *> (i->o)&&dynamic_cast<const CGVisitableOPW *> (i->o)->visited)//don't visit things that have already been visited this week.
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
@ -414,7 +430,7 @@ void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h
destination = i->o->getSightCenter(); destination = i->o->getSightCenter();
if(hpos.z==destination.z) //don't try to take a path from the underworld to the top or vice versa if(hpos.z==destination.z) //don't try to take a path from the underworld to the top or vice versa
{ { //TODO: fix get path so that it doesn't return a path unless z's are the same, or path goes through sub gate
if(m_cb->getPath(hpos,destination,h.h,path)) if(m_cb->getPath(hpos,destination,h.h,path))
{ {
path.convert(0); path.convert(0);
@ -445,7 +461,7 @@ void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h
} }
h.interestingPos = interestingPos; h.interestingPos = interestingPos;
if(h.remainingMovement>0&&m_cb->getPath(hpos,interestingPos,h.h,path)) // there ought to be a path // if(h.remainingMovement>0&&m_cb->getPath(hpos,interestingPos,h.h,path)) // there ought to be a path
currentHeroObjectives.insert(HeroObjective(hgs,HeroObjective::finishTurn,h.h,&h,this)); currentHeroObjectives.insert(HeroObjective(hgs,HeroObjective::finishTurn,h.h,&h,this));
@ -469,7 +485,7 @@ void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg,HypotheticalGameState & hg
hpos = h->pos; hpos = h->pos;
destination = h->interestingPos; destination = h->interestingPos;
if(!cg.m_cb->getPath(hpos,destination,h->h,path)) {cout << "AI error: invalid destination" << endl; return;} if(!cg.m_cb->getPath(hpos,destination,h->h,path)) {cout << "AI error: invalid destination" << endl; return;}
// path.convert(0);
destination = h->pos; destination = h->pos;
for(int i = path.nodes.size()-2;i>=0;i--) //find closest coord that we can get to for(int i = path.nodes.size()-2;i>=0;i--) //find closest coord that we can get to
if(cg.m_cb->getPath(hpos,path.nodes[i].coord,h->h,path2)&&path2.nodes[0].dist<=h->remainingMovement) if(cg.m_cb->getPath(hpos,path.nodes[i].coord,h->h,path2)&&path2.nodes[0].dist<=h->remainingMovement)
@ -506,43 +522,13 @@ void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg,HypotheticalGameState & hg
destination = bestPos; destination = bestPos;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
cg.m_cb->getPath(hpos,destination,h->h,path);
path.convert(0);
break; break;
case visit:case attack: case visit:case attack:
float bestCost = 9e9;
int bestHero = 0;
vector<int> resourceCosts;
for(int i = 0; i < 8;i++)
resourceCosts.push_back(0);
for(int i = 0; i < whoCanAchieve.size();i++)
{
int distOutOfTheWay = 0;
CPath path;
//from hero to object
if(AI->m_cb->getPath(whoCanAchieve[i]->pos,pos,whoCanAchieve[i]->h,path)) distOutOfTheWay+=path.nodes[0].dist;
//from object to goal
if(AI->m_cb->getPath(pos,whoCanAchieve[i]->interestingPos,whoCanAchieve[i]->h,path))
{
distOutOfTheWay+=path.nodes[0].dist;
//from hero directly to goal
if(AI->m_cb->getPath(whoCanAchieve[i]->pos,whoCanAchieve[i]->interestingPos,whoCanAchieve[i]->h,path)) distOutOfTheWay-=path.nodes[0].dist;
}
h = whoCanAchieve.front(); //lowest cost hero
float cost = AI->m_priorities->getCost(resourceCosts,whoCanAchieve[i]->h,distOutOfTheWay);
if(cost < bestCost)
{
bestCost = cost;
bestHero = i;
}
}
h = whoCanAchieve[bestHero]; //lowest cost hero
h->previouslyVisited_pos=object->getSightCenter(); 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; hpos = h->pos;
destination = object->getSightCenter(); destination = object->getSightCenter();
@ -669,7 +655,6 @@ void CGeniusAI::addTownObjectives(HypotheticalGameState::TownModel &t, Hypotheti
{ {
TownObjective to(hgs,AIObjective::buildBuilding,&t,i->first,this); TownObjective to(hgs,AIObjective::buildBuilding,&t,i->first,this);
currentTownObjectives.insert(to); currentTownObjectives.insert(to);
//cout <<"can build " << i->first << " "<< i->second->Name() << endl;
} }
} }
} }
@ -693,8 +678,8 @@ void CGeniusAI::addTownObjectives(HypotheticalGameState::TownModel &t, Hypotheti
currentTownObjectives.insert(to); currentTownObjectives.insert(to);
} }
//upgradeCreatures
//upgradeCreatures
for(std::map<si32,std::pair<ui32,si32> >::iterator i = t.creaturesInGarrison.slots.begin();i!=t.creaturesInGarrison.slots.end();i++) for(std::map<si32,std::pair<ui32,si32> >::iterator i = t.creaturesInGarrison.slots.begin();i!=t.creaturesInGarrison.slots.end();i++)
{ {
@ -702,10 +687,11 @@ void CGeniusAI::addTownObjectives(HypotheticalGameState::TownModel &t, Hypotheti
if(ui.newID.size()!=0) if(ui.newID.size()!=0)
{ {
bool canAfford = true; bool canAfford = true;
for(int ii=0;ii<ui.cost.size();ii++)
for (std::set<std::pair<int,int> >::iterator j=ui.cost[ii].begin(); j!=ui.cost[ii].end(); j++) int upgrade_serial = ui.newID.size()-1;
if(hgs.resourceAmounts[j->first] < j->second*i->second.second) for (std::set<std::pair<int,int> >::iterator j=ui.cost[upgrade_serial].begin(); j!=ui.cost[upgrade_serial].end(); j++)
canAfford = false; if(hgs.resourceAmounts[j->first] < j->second*i->second.second)
canAfford = false;
if(canAfford) if(canAfford)
{ {
TownObjective to(hgs,AIObjective::upgradeCreatures,&t,i->first,this); TownObjective to(hgs,AIObjective::upgradeCreatures,&t,i->first,this);
@ -1034,13 +1020,17 @@ void CGeniusAI::battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile,
*/ */
void CGeniusAI::battleEnd(BattleResult *br) void CGeniusAI::battleEnd(BattleResult *br)
{ {
switch(br->winner) switch(br->winner)
{ {
case 0: std::cout << "The winner is the attacker." << std::endl;break; case 0: std::cout << "The winner is the attacker." << std::endl;break;
case 1: std::cout << "The winner is the defender." << std::endl;break; case 1: std::cout << "The winner is the defender." << std::endl;break;
case 2: std::cout << "It's a draw." << std::endl;break; case 2: std::cout << "It's a draw." << std::endl;break;
}; };
cout << "lost ";
for(std::set<std::pair<ui32,si32> >::iterator i = br->casualties[0].begin(); i !=br->casualties[0].end();i++)
cout << i->second << " " << VLC->creh->creatures[i->first].namePl << endl;
delete m_battleLogic; delete m_battleLogic;
m_battleLogic = NULL; m_battleLogic = NULL;

View File

@ -110,10 +110,10 @@ private:
HypotheticalGameState hgs; HypotheticalGameState hgs;
int3 pos; int3 pos;
const CGObjectInstance * object; const CGObjectInstance * object;
std::vector<HypotheticalGameState::HeroModel *> whoCanAchieve; mutable std::vector<HypotheticalGameState::HeroModel *> whoCanAchieve;
HeroObjective(){} //HeroObjective(){}
HeroObjective(Type t):object(NULL){type = t;} //HeroObjective(Type t):object(NULL){type = t;}
HeroObjective(const HypotheticalGameState &hgs,Type t,const CGObjectInstance * object,HypotheticalGameState::HeroModel *h,CGeniusAI * AI); HeroObjective(const HypotheticalGameState &hgs,Type t,const CGObjectInstance * object,HypotheticalGameState::HeroModel *h,CGeniusAI * AI);
bool operator < (const HeroObjective &other)const; bool operator < (const HeroObjective &other)const;
void fulfill(CGeniusAI &,HypotheticalGameState & hgs); void fulfill(CGeniusAI &,HypotheticalGameState & hgs);