mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Rewritten VCAI::pickBestCreatures. Should fix the compilation error ( http://forum.vcmi.eu/viewtopic.php?p=6605#6605 ).
This commit is contained in:
parent
59681be0a4
commit
76eb0ed429
@ -863,6 +863,10 @@ void VCAI::makeTurnInternal()
|
|||||||
blockedHeroes.clear();
|
blockedHeroes.clear();
|
||||||
saving = 0;
|
saving = 0;
|
||||||
|
|
||||||
|
//it looks messy here, but it's better to have armed heroes before attempting realizing goals
|
||||||
|
BOOST_FOREACH(const CGTownInstance *t, cb->getTownsInfo())
|
||||||
|
moveCreaturesToHero(t);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
striveToGoal(CGoal(WIN));
|
striveToGoal(CGoal(WIN));
|
||||||
@ -901,7 +905,7 @@ void VCAI::performObjectInteraction(const CGObjectInstance * obj, const CGHeroIn
|
|||||||
|
|
||||||
void VCAI::moveCreaturesToHero(const CGTownInstance * t)
|
void VCAI::moveCreaturesToHero(const CGTownInstance * t)
|
||||||
{
|
{
|
||||||
if(t->visitingHero)
|
if(t->visitingHero && t->armedGarrison())
|
||||||
{
|
{
|
||||||
pickBestCreatures (t->visitingHero, t);
|
pickBestCreatures (t->visitingHero, t);
|
||||||
}
|
}
|
||||||
@ -909,56 +913,37 @@ void VCAI::moveCreaturesToHero(const CGTownInstance * t)
|
|||||||
|
|
||||||
void VCAI::pickBestCreatures(const CArmedInstance * army, const CArmedInstance * source)
|
void VCAI::pickBestCreatures(const CArmedInstance * army, const CArmedInstance * source)
|
||||||
{
|
{
|
||||||
if (army->stacksCount() == GameConstants::ARMY_SIZE) //try merging our army first
|
//TODO - what if source is a hero (the last stack problem) -> it'd good to create a single stack of weakest cre
|
||||||
|
const CArmedInstance *armies[] = {army, source};
|
||||||
|
//we calculate total strength for each creature type available in armies
|
||||||
|
std::map<const CCreature*, int> creToPower;
|
||||||
|
BOOST_FOREACH(auto armyPtr, armies)
|
||||||
|
BOOST_FOREACH(auto &i, armyPtr->Slots())
|
||||||
|
creToPower[i.second->type] += i.second->getPower();
|
||||||
|
//TODO - consider more than just power (ie morale penalty, hero specialty in certain stacks, etc)
|
||||||
|
|
||||||
|
std::vector<const CCreature *> bestArmy; //types that'll be in final dst army
|
||||||
|
for (int i = 0; i < GameConstants::ARMY_SIZE; i++) //pick the creatures from which we can get most power, as many as dest can fit
|
||||||
{
|
{
|
||||||
for (int i = 0; i < GameConstants::ARMY_SIZE; ++i)
|
typedef const std::pair<const CCreature*, int> &CrePowerPair;
|
||||||
{
|
auto creIt = boost::max_element(creToPower, [](CrePowerPair lhs, CrePowerPair rhs)
|
||||||
if (const CStackInstance *s = army->getStackPtr(i))
|
|
||||||
{
|
{
|
||||||
for (int j = 0; j < GameConstants::ARMY_SIZE; ++j)
|
return lhs.second < rhs.second;
|
||||||
{
|
});
|
||||||
if (i != j && army->mergableStacks(std::pair<TSlot, TSlot>(i, j)))
|
bestArmy.push_back(creIt->first);
|
||||||
{
|
creToPower.erase(creIt);
|
||||||
cb->mergeStacks (army, army, j, i);
|
if(creToPower.empty())
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < GameConstants::ARMY_SIZE; ++i)
|
//foreach best type -> iterate over slots in both armies and if it's the appropriate type, send it to the slot where it belongs
|
||||||
{
|
for (int i = 0; i < bestArmy.size(); i++) //i-th strongest creature type will go to i-th slot
|
||||||
if(const CStackInstance *s = source->getStackPtr(i))
|
BOOST_FOREACH(auto armyPtr, armies)
|
||||||
{
|
for (int j = 0; j < GameConstants::ARMY_SIZE; j++)
|
||||||
//find d
|
if(armyPtr->getCreature(j) == bestArmy[i] && (i != j || armyPtr != army)) //it's a searched creature not in dst slot
|
||||||
int dstSlot = army->getSlotFor(s->type);
|
cb->mergeOrSwapStacks(armyPtr, army, j, i);
|
||||||
if(dstSlot >= 0)
|
|
||||||
{
|
//TODO - having now strongest possible army, we may want to think about arranging stacks
|
||||||
if (army->hasStackAtSlot(dstSlot))
|
|
||||||
cb->mergeStacks(source, army, i, dstSlot);
|
|
||||||
else
|
|
||||||
cb->swapCreatures(source, army, i, dstSlot);
|
|
||||||
}
|
|
||||||
else //exchange poorest stack with stronger one
|
|
||||||
{
|
|
||||||
TSlot weakestStack = 0;
|
|
||||||
for (int j = 1; j < GameConstants::ARMY_SIZE; ++j)
|
|
||||||
{
|
|
||||||
const CStackInstance *p = army->getStackPtr(j);
|
|
||||||
const CStackInstance *w = army->getStackPtr(weakestStack);
|
|
||||||
if (p && w)
|
|
||||||
{
|
|
||||||
if (p->getPower() < w->getPower())
|
|
||||||
weakestStack = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (const CStackInstance *w = army->getStackPtr(weakestStack))
|
|
||||||
if (w->getPower() < s->getPower())
|
|
||||||
cb->swapCreatures(source, army, i, weakestStack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCAI::recruitCreatures(const CGDwelling * d)
|
void VCAI::recruitCreatures(const CGDwelling * d)
|
||||||
|
@ -403,6 +403,14 @@ void CCallback::validatePaths()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CCallback::mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)
|
||||||
|
{
|
||||||
|
if(s1->getCreature(p1) == s2->getCreature(p2))
|
||||||
|
return mergeStacks(s1, s2, p1, p2);
|
||||||
|
else
|
||||||
|
return swapCreatures(s1, s2, p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
CBattleCallback::CBattleCallback(CGameState *GS, int Player, CClient *C )
|
CBattleCallback::CBattleCallback(CGameState *GS, int Player, CClient *C )
|
||||||
{
|
{
|
||||||
gs = GS;
|
gs = GS;
|
||||||
|
@ -60,6 +60,7 @@ public:
|
|||||||
virtual void selectionMade(int selection, int asker) =0;
|
virtual void selectionMade(int selection, int asker) =0;
|
||||||
virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//swaps creatures between two possibly different garrisons // TODO: AI-unsafe code - fix it!
|
virtual int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//swaps creatures between two possibly different garrisons // TODO: AI-unsafe code - fix it!
|
||||||
virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//joins first stack to the second (creatures must be same type)
|
virtual int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2)=0;//joins first stack to the second (creatures must be same type)
|
||||||
|
virtual int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2) =0; //first goes to the second
|
||||||
virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack
|
virtual int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack
|
||||||
//virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes
|
//virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes
|
||||||
virtual bool swapArtifacts(const IArtifactSetBase * src, ui16 pos1, const IArtifactSetBase * dest, ui16 pos2)=0;
|
virtual bool swapArtifacts(const IArtifactSetBase * src, ui16 pos1, const IArtifactSetBase * dest, ui16 pos2)=0;
|
||||||
@ -121,6 +122,7 @@ public:
|
|||||||
bool teleportHero(const CGHeroInstance *who, const CGTownInstance *where);
|
bool teleportHero(const CGHeroInstance *who, const CGTownInstance *where);
|
||||||
void selectionMade(int selection, int asker);
|
void selectionMade(int selection, int asker);
|
||||||
int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2);
|
int swapCreatures(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2);
|
||||||
|
int mergeOrSwapStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); //first goes to the second
|
||||||
int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); //first goes to the second
|
int mergeStacks(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2); //first goes to the second
|
||||||
int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val);
|
int splitStack(const CArmedInstance *s1, const CArmedInstance *s2, int p1, int p2, int val);
|
||||||
bool dismissHero(const CGHeroInstance * hero);
|
bool dismissHero(const CGHeroInstance * hero);
|
||||||
|
Loading…
Reference in New Issue
Block a user