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
34 16 17
o 34 16 17
R
47 16
o 47 16
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
98 16 17
o 98 16 17
R
98 16 17
o 98 16 17
R
100 16
o 100 16
R
38 16
o 38 16
R
61 16
o 61 16
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
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
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
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
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
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
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
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
28 16
o 28 16
R
81 16
o 81 16
R
83 25
o 83 25
R
31 16
o 31 16
R
57 24
o 57 24
R
23 16
o 23 16
R
102 16
o 102 16
R
37 24
o 37 24
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

View File

@ -28,6 +28,7 @@ Network::Network(istream & input)
float Network::feedForward(const vector<float> & stateFeatures)
{
return (rand()%1000)/800.0;
double * input = new double[whichFeatures.size()];
for(int i = 0; i < whichFeatures.size();i++)
input[i]=stateFeatures[whichFeatures[i]];
@ -38,37 +39,6 @@ float Network::feedForward(const vector<float> & stateFeatures)
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
:numSpecialFeatures(8)
{
@ -77,10 +47,26 @@ Priorities::Priorities(const string & filename) //read brain from file
// object_num [list of features]
// brain data or "R" for random brain
objectNetworks.resize(255);
buildingNetworks.resize(9);
char type;
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)
{ //resource
vector<int> resourceAmounts(8,0);
int amount;
if(obj.type==CGeniusAI::AIObjective::finishTurn) //TODO: replace with value of visiting that object divided by days till completed
return .0001; //small nonzero
float a;
if(obj.type==CGeniusAI::AIObjective::attack)
return 100;
if(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
return 0;
case 79:
case 79://resources on the ground
switch(hobj->object->subID)
{
case 6:
@ -235,7 +223,19 @@ float Priorities::getValue(const CGeniusAI::AIObjective & obj)
}
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
{
public:
Priorities(); //random brain
Priorities(const string & filename); //read brain from file
@ -33,6 +32,7 @@ public:
float getValue(const CGeniusAI::AIObjective & obj);
float getCost(vector<int> &resourceCosts,const CGHeroInstance * moved,int distOutOfTheWay);
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)
{
AI = &ai;
// knownVisitableObjects = ai.knownVisitableObjects;
knownVisitableObjects = ai.knownVisitableObjects;
std::vector<HeroModel> oldModels = heroModels;
heroModels.clear();
@ -122,22 +122,23 @@ float CGeniusAI::HeroObjective::getValue() const
resourceCosts[6]+=1000;
float bestCost = 9e9;
HypotheticalGameState::HeroModel * bestHero = NULL;
if(type !=AIObjective::finishTurn)
{
for(int i = 0; i < whoCanAchieve.size();i++)
{
int distOutOfTheWay = 0;
CPath path;
CPath path3;
//from hero to object
if(AI->m_cb->getPath(whoCanAchieve[i]->pos,pos,whoCanAchieve[i]->h,path))
distOutOfTheWay+=path.nodes[0].dist;
if(AI->m_cb->getPath(whoCanAchieve[i]->pos,pos,whoCanAchieve[i]->h,path3))
distOutOfTheWay+=path3.nodes[0].dist;
//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
if(AI->m_cb->getPath(whoCanAchieve[i]->pos,whoCanAchieve[i]->interestingPos,whoCanAchieve[i]->h,path))
distOutOfTheWay-=path.nodes[0].dist;
if(AI->m_cb->getPath(whoCanAchieve[i]->pos,whoCanAchieve[i]->interestingPos,whoCanAchieve[i]->h,path3))
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);
if(cost < bestCost)
{
bestCost = cost;
bestHero = whoCanAchieve[i];
}
}
}
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);
_cost=bestCost;
return _value-_cost;
@ -178,6 +187,7 @@ void CGeniusAI::HeroObjective::print() const
break;
case attack:
cout << "attack " << object->hoverName;
break;
case finishTurn:
cout << "finish turn";
}
@ -230,8 +240,9 @@ float CGeniusAI::TownObjective::getValue() const
ID = whichTown->creaturesInGarrison.slots[which].first;
howMany = whichTown->creaturesInGarrison.slots[which].second;
newID = ui.newID.back();
for(std::set<std::pair<int,int> >::iterator i = ui.cost[which].begin();i!=ui.cost[which].end();i++)
resourceCosts[i->first] = i->second*howMany;
int upgrade_serial = ui.newID.size()-1;
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;
@ -362,6 +373,7 @@ 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++)
{
tp = AIObjective::visit;
if( h.previouslyVisited_pos==i->o->getSightCenter())
continue;
//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.
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)
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())
{
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))
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))
enemyStrength = (dynamic_cast<const CGHeroInstance *> (i->o))->getHeroStrength();
enemyStrength = (dynamic_cast<const CGHeroInstance *> (i->o))->getTotalStrength();
if(dynamic_cast<const CGTownInstance *> (i->o))
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.
float heroStrength = h.h->getTotalStrength();
if(enemyStrength*2.5 > heroStrength) //TODO: ballence these numbers using objective cost formula.
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.
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
@ -414,7 +430,7 @@ void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h
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
{
{ //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))
{
path.convert(0);
@ -445,7 +461,7 @@ void CGeniusAI::addHeroObjectives(CGeniusAI::HypotheticalGameState::HeroModel &h
}
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));
@ -469,7 +485,7 @@ void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg,HypotheticalGameState & hg
hpos = h->pos;
destination = h->interestingPos;
if(!cg.m_cb->getPath(hpos,destination,h->h,path)) {cout << "AI error: invalid destination" << endl; return;}
// path.convert(0);
destination = h->pos;
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)
@ -506,43 +522,13 @@ void CGeniusAI::HeroObjective::fulfill(CGeniusAI & cg,HypotheticalGameState & hg
destination = bestPos;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
cg.m_cb->getPath(hpos,destination,h->h,path);
path.convert(0);
break;
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;
}
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 = whoCanAchieve.front(); //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;
destination = object->getSightCenter();
@ -669,7 +655,6 @@ void CGeniusAI::addTownObjectives(HypotheticalGameState::TownModel &t, Hypotheti
{
TownObjective to(hgs,AIObjective::buildBuilding,&t,i->first,this);
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);
}
//upgradeCreatures
//upgradeCreatures
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)
{
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++)
if(hgs.resourceAmounts[j->first] < j->second*i->second.second)
canAfford = false;
int upgrade_serial = ui.newID.size()-1;
for (std::set<std::pair<int,int> >::iterator j=ui.cost[upgrade_serial].begin(); j!=ui.cost[upgrade_serial].end(); j++)
if(hgs.resourceAmounts[j->first] < j->second*i->second.second)
canAfford = false;
if(canAfford)
{
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)
{
switch(br->winner)
{
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 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;
m_battleLogic = NULL;

View File

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