mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
AI pathfinding loss evaluation
This commit is contained in:
parent
594d1684e9
commit
1e4a086bb1
@ -70,7 +70,7 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta
|
||||
}
|
||||
}
|
||||
|
||||
void AINodeStorage::reset()
|
||||
void AINodeStorage::clear()
|
||||
{
|
||||
actors.clear();
|
||||
}
|
||||
@ -148,6 +148,7 @@ void AINodeStorage::resetTile(const int3 & coord, EPathfindingLayer layer, CGPat
|
||||
heroNode.danger = 0;
|
||||
heroNode.manaCost = 0;
|
||||
heroNode.specialAction.reset();
|
||||
heroNode.armyLoss = 0;
|
||||
heroNode.update(coord, layer, accessibility);
|
||||
}
|
||||
}
|
||||
@ -165,6 +166,7 @@ void AINodeStorage::commit(CDestinationNodeInfo & destination, const PathNodeInf
|
||||
dstNode->action = destination.action;
|
||||
dstNode->theNodeBefore = srcNode->theNodeBefore;
|
||||
dstNode->manaCost = srcNode->manaCost;
|
||||
dstNode->armyLoss = srcNode->armyLoss;
|
||||
|
||||
if(dstNode->specialAction && dstNode->actor)
|
||||
{
|
||||
@ -213,7 +215,7 @@ const std::set<const CGHeroInstance *> AINodeStorage::getAllHeroes() const
|
||||
for(auto actor : actors)
|
||||
{
|
||||
if(actor->hero)
|
||||
heroes.insert(hero);
|
||||
heroes.insert(actor->hero);
|
||||
}
|
||||
|
||||
return heroes;
|
||||
@ -255,7 +257,7 @@ std::vector<CGPathNode *> AINodeStorage::calculateTeleportations(
|
||||
}
|
||||
}
|
||||
|
||||
if(hero->getPosition(false) == source.coord)
|
||||
if(source.isInitialPosition)
|
||||
{
|
||||
calculateTownPortalTeleportations(source, neighbours);
|
||||
}
|
||||
@ -270,6 +272,7 @@ void AINodeStorage::calculateTownPortalTeleportations(
|
||||
SpellID spellID = SpellID::TOWN_PORTAL;
|
||||
const CSpell * townPortal = spellID.toSpell();
|
||||
auto srcNode = getAINode(source.node);
|
||||
auto hero = srcNode->actor->hero;
|
||||
|
||||
if(hero->canCastThisSpell(townPortal) && hero->mana >= hero->getSpellCost(townPortal))
|
||||
{
|
||||
@ -384,11 +387,10 @@ std::vector<AIPath> AINodeStorage::getChainInfo(const int3 & pos, bool isOnLand)
|
||||
{
|
||||
std::vector<AIPath> paths;
|
||||
auto chains = nodes[pos.x][pos.y][pos.z][isOnLand ? EPathfindingLayer::LAND : EPathfindingLayer::SAIL];
|
||||
auto initialPos = hero->visitablePos();
|
||||
|
||||
for(const AIPathNode & node : chains)
|
||||
{
|
||||
if(node.action == CGPathNode::ENodeAction::UNKNOWN || !node.actor)
|
||||
if(node.action == CGPathNode::ENodeAction::UNKNOWN || !node.actor || !node.actor->hero)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -397,6 +399,7 @@ std::vector<AIPath> AINodeStorage::getChainInfo(const int3 & pos, bool isOnLand)
|
||||
const AIPathNode * current = &node;
|
||||
|
||||
path.targetHero = node.actor->hero;
|
||||
auto initialPos = path.targetHero->visitablePos();
|
||||
|
||||
while(current != nullptr && current->coord != initialPos)
|
||||
{
|
||||
@ -412,7 +415,7 @@ std::vector<AIPath> AINodeStorage::getChainInfo(const int3 & pos, bool isOnLand)
|
||||
current = getAINode(current->theNodeBefore);
|
||||
}
|
||||
|
||||
path.targetObjectDanger = evaluateDanger(pos);
|
||||
path.targetObjectDanger = evaluateDanger(pos, path.targetHero);
|
||||
|
||||
paths.push_back(path);
|
||||
}
|
||||
@ -471,6 +474,7 @@ ChainActor::ChainActor(const CGHeroInstance * hero, int chainMask)
|
||||
layer = hero->boat ? EPathfindingLayer::SAIL : EPathfindingLayer::LAND;
|
||||
initialMovement = hero->movement;
|
||||
initialTurn = 0;
|
||||
armyValue = hero->getTotalStrength();
|
||||
|
||||
setupSpecialActors();
|
||||
}
|
||||
@ -500,7 +504,7 @@ void ChainActor::setupSpecialActors()
|
||||
allActors.push_back(&specialActor);
|
||||
}
|
||||
|
||||
for(int i = 0; i <= 8; i++)
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
ChainActor * actor = allActors[i];
|
||||
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
EPathfindingLayer layer;
|
||||
uint32_t initialMovement;
|
||||
uint32_t initialTurn;
|
||||
uint64_t armyValue;
|
||||
|
||||
ChainActor()
|
||||
{
|
||||
@ -51,6 +52,7 @@ public:
|
||||
struct AIPathNode : public CGPathNode
|
||||
{
|
||||
uint64_t danger;
|
||||
uint64_t armyLoss;
|
||||
uint32_t manaCost;
|
||||
std::shared_ptr<const ISpecialAction> specialAction;
|
||||
const ChainActor * actor;
|
||||
@ -93,7 +95,6 @@ private:
|
||||
boost::multi_array<AIPathNode, 5> nodes;
|
||||
const CPlayerSpecificInfoCallback * cb;
|
||||
const VCAI * ai;
|
||||
const CGHeroInstance * hero;
|
||||
std::unique_ptr<FuzzyHelper> dangerEvaluator;
|
||||
std::vector<std::shared_ptr<ChainActor>> actors;
|
||||
|
||||
@ -137,9 +138,9 @@ public:
|
||||
|
||||
const std::set<const CGHeroInstance *> getAllHeroes() const;
|
||||
|
||||
void reset();
|
||||
void clear();
|
||||
|
||||
uint64_t evaluateDanger(const int3 & tile) const
|
||||
uint64_t evaluateDanger(const int3 & tile, const CGHeroInstance * hero) const
|
||||
{
|
||||
return dangerEvaluator->evaluateDanger(tile, hero, ai);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ void AIPathfinder::updatePaths(std::vector<HeroPtr> heroes)
|
||||
|
||||
logAi->debug("Recalculate all paths");
|
||||
|
||||
storage.reset();
|
||||
storage->clear();
|
||||
storage->setHeroes(heroes, ai);
|
||||
|
||||
auto config = std::make_shared<AIPathfinding::AIPathfinderConfig>(cb, ai, storage);
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "../../AIUtility.h"
|
||||
#include "../../Goals/AbstractGoal.h"
|
||||
|
||||
class AIPathNode;
|
||||
struct AIPathNode;
|
||||
|
||||
class ISpecialAction
|
||||
{
|
||||
|
@ -121,25 +121,32 @@ namespace AIPathfinding
|
||||
return;
|
||||
}
|
||||
|
||||
auto danger = nodeStorage->evaluateDanger(destination.coord);
|
||||
auto hero = nodeStorage->getHero(source.node);
|
||||
auto danger = nodeStorage->evaluateDanger(destination.coord, hero);
|
||||
double actualArmyValue = srcNode->actor->armyValue - srcNode->armyLoss;
|
||||
double ratio = (double)danger / actualArmyValue;
|
||||
|
||||
destination.node = battleNode;
|
||||
nodeStorage->commit(destination, source);
|
||||
uint64_t loss = (uint64_t)(actualArmyValue * ratio * ratio * ratio);
|
||||
|
||||
if(battleNode->danger < danger)
|
||||
if(loss < actualArmyValue)
|
||||
{
|
||||
battleNode->danger = danger;
|
||||
}
|
||||
destination.node = battleNode;
|
||||
nodeStorage->commit(destination, source);
|
||||
|
||||
battleNode->specialAction = std::make_shared<BattleAction>(destination.coord);
|
||||
battleNode->armyLoss += loss;
|
||||
|
||||
vstd::amax(battleNode->danger, danger);
|
||||
|
||||
battleNode->specialAction = std::make_shared<BattleAction>(destination.coord);
|
||||
#ifdef VCMI_TRACE_PATHFINDER
|
||||
logAi->trace(
|
||||
"Begin bypass guard at destination with danger %s while moving %s -> %s",
|
||||
std::to_string(danger),
|
||||
source.coord.toString(),
|
||||
destination.coord.toString());
|
||||
logAi->trace(
|
||||
"Begin bypass guard at destination with danger %s while moving %s -> %s",
|
||||
std::to_string(danger),
|
||||
source.coord.toString(),
|
||||
destination.coord.toString());
|
||||
#endif
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
destination.blocked = true;
|
||||
|
Loading…
Reference in New Issue
Block a user