1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

AI: hero chain stabilisation

This commit is contained in:
Andrii Danylchenko
2021-05-15 21:54:28 +03:00
committed by Andrii Danylchenko
parent 3a0d9fe14e
commit 0e328ab3c2
6 changed files with 55 additions and 38 deletions

View File

@@ -172,6 +172,12 @@ void AINodeStorage::commit(CDestinationNodeInfo & destination, const PathNodeInf
{ {
commit(dstNode, srcNode, destination.action, destination.turn, destination.movementLeft, destination.cost); commit(dstNode, srcNode, destination.action, destination.turn, destination.movementLeft, destination.cost);
if(srcNode->specialAction || srcNode->chainOther)
{
// there is some action on source tile which should be performed before we can bypass it
destination.node->theNodeBefore = source.node;
}
if(dstNode->specialAction && dstNode->actor) if(dstNode->specialAction && dstNode->actor)
{ {
dstNode->specialAction->applyOnDestination(dstNode->actor->hero, destination, source, dstNode, srcNode); dstNode->specialAction->applyOnDestination(dstNode->actor->hero, destination, source, dstNode, srcNode);
@@ -183,7 +189,7 @@ void AINodeStorage::commit(CDestinationNodeInfo & destination, const PathNodeInf
source.coord.toString(), source.coord.toString(),
destination.coord.toString(), destination.coord.toString(),
destination.cost, destination.cost,
dstNode->actor->hero->name, dstNode->actor->toString(),
dstNode->actor->chainMask); dstNode->actor->chainMask);
#endif #endif
}); });
@@ -251,14 +257,20 @@ bool AINodeStorage::calculateHeroChain()
for(AIPathNode & node : chains) for(AIPathNode & node : chains)
{ {
if(node.coord.x == 60 && node.coord.y == 56 && node.actor)
logAi->trace(node.actor->toString());
if(node.turns <= heroChainMaxTurns && node.action != CGPathNode::ENodeAction::UNKNOWN) if(node.turns <= heroChainMaxTurns && node.action != CGPathNode::ENodeAction::UNKNOWN)
buffer.push_back(&node); buffer.push_back(&node);
} }
for(AIPathNode * node : buffer) for(AIPathNode * node : buffer)
{
if(node->actor->hero)
{ {
addHeroChain(node, buffer); addHeroChain(node, buffer);
} }
}
}); });
return heroChain.size(); return heroChain.size();
@@ -277,9 +289,9 @@ void AINodeStorage::addHeroChain(AIPathNode * srcNode, std::vector<AIPathNode *>
#ifdef VCMI_TRACE_PATHFINDER_EX #ifdef VCMI_TRACE_PATHFINDER_EX
logAi->trace( logAi->trace(
"Thy exchange %s[%i] -> %s[%i] at %s", "Thy exchange %s[%i] -> %s[%i] at %s",
node->actor->hero->name, node->actor->toString(),
node->actor->chainMask, node->actor->chainMask,
srcNode->actor->hero->name, srcNode->actor->toString(),
srcNode->actor->chainMask, srcNode->actor->chainMask,
srcNode->coord.toString()); srcNode->coord.toString());
#endif #endif
@@ -299,9 +311,9 @@ void AINodeStorage::addHeroChain(AIPathNode * carrier, AIPathNode * other)
#ifdef VCMI_TRACE_PATHFINDER_EX #ifdef VCMI_TRACE_PATHFINDER_EX
logAi->trace( logAi->trace(
"Exchange allowed %s[%i] -> %s[%i] at %s", "Exchange allowed %s[%i] -> %s[%i] at %s",
other->actor->hero->name, other->actor->toString(),
other->actor->chainMask, other->actor->chainMask,
carrier->actor->hero->name, carrier->actor->toString(),
carrier->actor->chainMask, carrier->actor->chainMask,
carrier->coord.toString()); carrier->coord.toString());
#endif #endif
@@ -344,8 +356,8 @@ void AINodeStorage::addHeroChain(AIPathNode * carrier, AIPathNode * other)
logAi->trace( logAi->trace(
"Chain accepted at %s %s -> %s, mask %i, cost %f", "Chain accepted at %s %s -> %s, mask %i, cost %f",
chainNode->coord.toString(), chainNode->coord.toString(),
other->actor->hero->name, other->actor->toString(),
chainNode->actor->hero->name, chainNode->actor->toString(),
chainNode->actor->chainMask, chainNode->actor->chainMask,
chainNode->cost); chainNode->cost);
#endif #endif
@@ -430,7 +442,7 @@ void AINodeStorage::setHeroes(std::vector<HeroPtr> heroes, const VCAI * _ai)
void AINodeStorage::setTownsAndDwellings( void AINodeStorage::setTownsAndDwellings(
const std::vector<const CGTownInstance *> & towns, const std::vector<const CGTownInstance *> & towns,
const std::vector<const CGObjectInstance *> & visitableObjs) const std::set<const CGObjectInstance *> & visitableObjs)
{ {
for(auto town : towns) for(auto town : towns)
{ {

View File

@@ -85,7 +85,7 @@ private:
public: public:
/// more than 1 chain layer for each hero allows us to have more than 1 path to each tile so we can chose more optimal one. /// more than 1 chain layer for each hero allows us to have more than 1 path to each tile so we can chose more optimal one.
static const int NUM_CHAINS = 3 * GameConstants::MAX_HEROES_PER_PLAYER; static const int NUM_CHAINS = 5 * GameConstants::MAX_HEROES_PER_PLAYER;
AINodeStorage(const int3 & sizes); AINodeStorage(const int3 & sizes);
~AINodeStorage(); ~AINodeStorage();
@@ -116,7 +116,7 @@ public:
void setHeroes(std::vector<HeroPtr> heroes, const VCAI * ai); void setHeroes(std::vector<HeroPtr> heroes, const VCAI * ai);
void setTownsAndDwellings( void setTownsAndDwellings(
const std::vector<const CGTownInstance *> & towns, const std::vector<const CGTownInstance *> & towns,
const std::vector<const CGObjectInstance *> & visitableObjs); const std::set<const CGObjectInstance *> & visitableObjs);
const CGHeroInstance * getHero(const CGPathNode * node) const; const CGHeroInstance * getHero(const CGPathNode * node) const;
const std::set<const CGHeroInstance *> getAllHeroes() const; const std::set<const CGHeroInstance *> getAllHeroes() const;
void clear(); void clear();

View File

@@ -56,6 +56,11 @@ void AIPathfinder::updatePaths(std::vector<HeroPtr> heroes, bool useHeroChain)
storage->clear(); storage->clear();
storage->setHeroes(heroes, ai); storage->setHeroes(heroes, ai);
if(useHeroChain)
{
storage->setTownsAndDwellings(cb->getTownsInfo(), ai->visitableObjs);
}
auto config = std::make_shared<AIPathfinding::AIPathfinderConfig>(cb, ai, storage); auto config = std::make_shared<AIPathfinding::AIPathfinderConfig>(cb, ai, storage);
do { do {

View File

@@ -16,23 +16,6 @@
#include "../../../lib/mapping/CMap.h" #include "../../../lib/mapping/CMap.h"
#include "../../../lib/mapObjects/MapObjects.h" #include "../../../lib/mapObjects/MapObjects.h"
class ExchangeAction : public ISpecialAction
{
private:
const CGHeroInstance * target;
const CGHeroInstance * source;
public:
ExchangeAction(const CGHeroInstance * target, const CGHeroInstance * source)
:target(target), source(source)
{ }
virtual Goals::TSubgoal whatToDo(const HeroPtr & hero) const override
{
return Goals::sptr(Goals::VisitHero(target->id.getNum()).sethero(hero));
}
};
ChainActor::ChainActor(const CGHeroInstance * hero, uint64_t chainMask) ChainActor::ChainActor(const CGHeroInstance * hero, uint64_t chainMask)
:hero(hero), isMovable(true), chainMask(chainMask), creatureSet(hero), :hero(hero), isMovable(true), chainMask(chainMask), creatureSet(hero),
baseActor(this), carrierParent(nullptr), otherParent(nullptr) baseActor(this), carrierParent(nullptr), otherParent(nullptr)
@@ -60,6 +43,11 @@ ChainActor::ChainActor(const CGObjectInstance * obj, const CCreatureSet * creatu
armyValue = creatureSet->getArmyStrength(); armyValue = creatureSet->getArmyStrength();
} }
std::string ChainActor::toString() const
{
return hero->name;
}
HeroActor::HeroActor(const CGHeroInstance * hero, uint64_t chainMask, const VCAI * ai) HeroActor::HeroActor(const CGHeroInstance * hero, uint64_t chainMask, const VCAI * ai)
:ChainActor(hero, chainMask) :ChainActor(hero, chainMask)
{ {
@@ -213,7 +201,8 @@ DwellingActor::DwellingActor(const CGDwelling * dwelling, uint64_t chainMask, bo
dwelling, dwelling,
getDwellingCreatures(dwelling, waitForGrowth), getDwellingCreatures(dwelling, waitForGrowth),
chainMask, chainMask,
getInitialTurn(waitForGrowth, dayOfWeek)) getInitialTurn(waitForGrowth, dayOfWeek)),
dwelling(dwelling)
{ {
} }
@@ -230,6 +219,11 @@ int DwellingActor::getInitialTurn(bool waitForGrowth, int dayOfWeek)
return 8 - dayOfWeek; return 8 - dayOfWeek;
} }
std::string DwellingActor::toString() const
{
return dwelling->typeName + dwelling->visitablePos().toString();
}
CCreatureSet * DwellingActor::getDwellingCreatures(const CGDwelling * dwelling, bool waitForGrowth) CCreatureSet * DwellingActor::getDwellingCreatures(const CGDwelling * dwelling, bool waitForGrowth)
{ {
CCreatureSet * dwellingCreatures = new CCreatureSet(); CCreatureSet * dwellingCreatures = new CCreatureSet();
@@ -259,6 +253,11 @@ CCreatureSet * DwellingActor::getDwellingCreatures(const CGDwelling * dwelling,
} }
TownGarrisonActor::TownGarrisonActor(const CGTownInstance * town, uint64_t chainMask) TownGarrisonActor::TownGarrisonActor(const CGTownInstance * town, uint64_t chainMask)
:ChainActor(town, town->getUpperArmy(), chainMask, 0) :ChainActor(town, town->getUpperArmy(), chainMask, 0), town(town)
{ {
} }
std::string TownGarrisonActor::toString() const
{
return town->name;
}

View File

@@ -48,6 +48,7 @@ public:
ChainActor(){} ChainActor(){}
virtual bool canExchange(const ChainActor * other) const; virtual bool canExchange(const ChainActor * other) const;
virtual std::string toString() const;
ChainActor * exchange(const ChainActor * other) const { return exchange(this, other); } ChainActor * exchange(const ChainActor * other) const { return exchange(this, other); }
void setBaseActor(HeroActor * base); void setBaseActor(HeroActor * base);
@@ -102,9 +103,13 @@ protected:
class DwellingActor : public ChainActor class DwellingActor : public ChainActor
{ {
private:
const CGDwelling * dwelling;
public: public:
DwellingActor(const CGDwelling * dwelling, uint64_t chainMask, bool waitForGrowth, int dayOfWeek); DwellingActor(const CGDwelling * dwelling, uint64_t chainMask, bool waitForGrowth, int dayOfWeek);
~DwellingActor(); ~DwellingActor();
virtual std::string toString() const override;
protected: protected:
int getInitialTurn(bool waitForGrowth, int dayOfWeek); int getInitialTurn(bool waitForGrowth, int dayOfWeek);
@@ -113,6 +118,10 @@ protected:
class TownGarrisonActor : public ChainActor class TownGarrisonActor : public ChainActor
{ {
private:
const CGTownInstance * town;
public: public:
TownGarrisonActor(const CGTownInstance * town, uint64_t chainMask); TownGarrisonActor(const CGTownInstance * town, uint64_t chainMask);
virtual std::string toString() const override;
}; };

View File

@@ -35,13 +35,5 @@ namespace AIPathfinding
#endif #endif
return; return;
} }
auto srcNode = nodeStorage->getAINode(source.node);
if(srcNode->specialAction || srcNode->chainOther)
{
// there is some action on source tile which should be performed before we can bypass it
destination.node->theNodeBefore = source.node;
}
} }
} }