mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
AI pathfinding calculated in parallel
This commit is contained in:
parent
35f696b695
commit
675406589c
@ -216,6 +216,11 @@ ui64 evaluateDanger(crint3 tile)
|
||||
}
|
||||
|
||||
ui64 evaluateDanger(crint3 tile, const CGHeroInstance * visitor)
|
||||
{
|
||||
return evaluateDanger(tile, visitor, cb.get());
|
||||
}
|
||||
|
||||
ui64 evaluateDanger(crint3 tile, const CGHeroInstance * visitor, const CPlayerSpecificInfoCallback * cb)
|
||||
{
|
||||
const TerrainTile * t = cb->getTile(tile, false);
|
||||
if(!t) //we can know about guard but can't check its tile (the edge of fow)
|
||||
|
@ -167,6 +167,7 @@ bool isWeeklyRevisitable(const CGObjectInstance * obj);
|
||||
bool shouldVisit(HeroPtr h, const CGObjectInstance * obj);
|
||||
|
||||
ui64 evaluateDanger(const CGObjectInstance * obj);
|
||||
ui64 evaluateDanger(crint3 tile, const CGHeroInstance * visitor, const CPlayerSpecificInfoCallback * cb);
|
||||
ui64 evaluateDanger(crint3 tile, const CGHeroInstance * visitor);
|
||||
bool isObjectRemovable(const CGObjectInstance * obj); //FIXME FIXME: move logic to object property!
|
||||
bool isSafeToVisit(HeroPtr h, uint64_t dangerStrength);
|
||||
|
@ -202,6 +202,8 @@ TacticalAdvantageEngine::TacticalAdvantageEngine()
|
||||
|
||||
float TacticalAdvantageEngine::getTacticalAdvantage(const CArmedInstance * we, const CArmedInstance * enemy)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(mx);
|
||||
|
||||
float output = 1;
|
||||
try
|
||||
{
|
||||
|
@ -35,6 +35,7 @@ private:
|
||||
fl::InputVariable * bankPresent;
|
||||
fl::InputVariable * castleWalls;
|
||||
fl::OutputVariable * threat;
|
||||
boost::mutex mx;
|
||||
};
|
||||
|
||||
class HeroMovementGoalEngineBase : public engineBase //in future - maybe derive from some (GoalEngineBase : public engineBase) class for handling non-movement goals with common utility for goal engines
|
||||
|
@ -17,9 +17,6 @@
|
||||
#include "../../../lib/PathfinderUtil.h"
|
||||
#include "../../../lib/CPlayerState.h"
|
||||
|
||||
extern boost::thread_specific_ptr<CCallback> cb;
|
||||
|
||||
|
||||
AINodeStorage::AINodeStorage(const int3 & Sizes)
|
||||
: sizes(Sizes)
|
||||
{
|
||||
@ -187,9 +184,10 @@ std::vector<CGPathNode *> AINodeStorage::calculateNeighbours(
|
||||
return neighbours;
|
||||
}
|
||||
|
||||
void AINodeStorage::setHero(HeroPtr heroPtr)
|
||||
void AINodeStorage::setHero(HeroPtr heroPtr, const CPlayerSpecificInfoCallback * _cb)
|
||||
{
|
||||
hero = heroPtr.get();
|
||||
cb = _cb;
|
||||
}
|
||||
|
||||
std::vector<CGPathNode *> AINodeStorage::calculateTeleportations(
|
||||
|
@ -59,6 +59,7 @@ private:
|
||||
|
||||
/// 1-3 - position on map, 4 - layer (air, water, land), 5 - chain (normal, battle, spellcast and combinations)
|
||||
boost::multi_array<AIPathNode, 5> nodes;
|
||||
const CPlayerSpecificInfoCallback * cb;
|
||||
const CGHeroInstance * hero;
|
||||
|
||||
STRONG_INLINE
|
||||
@ -102,7 +103,7 @@ public:
|
||||
std::vector<AIPath> getChainInfo(const int3 & pos, bool isOnLand) const;
|
||||
bool isTileAccessible(const int3 & pos, const EPathfindingLayer layer) const;
|
||||
|
||||
void setHero(HeroPtr heroPtr);
|
||||
void setHero(HeroPtr heroPtr, const CPlayerSpecificInfoCallback * cb);
|
||||
|
||||
const CGHeroInstance * getHero() const
|
||||
{
|
||||
|
@ -53,6 +53,15 @@ void AIPathfinder::updatePaths(std::vector<HeroPtr> heroes)
|
||||
{
|
||||
storageMap.clear();
|
||||
|
||||
auto calculatePaths = [&](const CGHeroInstance * hero, std::shared_ptr<AIPathfinding::AIPathfinderConfig> config)
|
||||
{
|
||||
logAi->debug("Recalculate paths for %s", hero->name);
|
||||
|
||||
cb->calculatePaths(config, hero);
|
||||
};
|
||||
|
||||
std::vector<Task> calculationTasks;
|
||||
|
||||
// TODO: go parallel?
|
||||
for(HeroPtr hero : heroes)
|
||||
{
|
||||
@ -69,12 +78,29 @@ void AIPathfinder::updatePaths(std::vector<HeroPtr> heroes)
|
||||
}
|
||||
|
||||
storageMap[hero] = nodeStorage;
|
||||
nodeStorage->setHero(hero.get());
|
||||
nodeStorage->setHero(hero, cb);
|
||||
|
||||
auto config = std::make_shared<AIPathfinding::AIPathfinderConfig>(cb, ai, nodeStorage);
|
||||
|
||||
logAi->debug("Recalculate paths for %s", hero->name);
|
||||
cb->calculatePaths(config, hero.get());
|
||||
calculationTasks.push_back(std::bind(calculatePaths, hero.get(), config));
|
||||
}
|
||||
|
||||
int threadsCount = std::min(
|
||||
boost::thread::hardware_concurrency(),
|
||||
(uint32_t)calculationTasks.size());
|
||||
|
||||
if(threadsCount == 1)
|
||||
{
|
||||
for(auto task : calculationTasks)
|
||||
{
|
||||
task();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CThreadHelper helper(&calculationTasks, threadsCount);
|
||||
|
||||
helper.run();
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +121,7 @@ void AIPathfinder::updatePaths(const HeroPtr & hero)
|
||||
}
|
||||
|
||||
storageMap[hero] = nodeStorage;
|
||||
nodeStorage->setHero(hero.get());
|
||||
nodeStorage->setHero(hero, cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ namespace AIPathfinding
|
||||
}
|
||||
|
||||
void SummonBoatAction::applyOnDestination(
|
||||
const HeroPtr & hero,
|
||||
const CGHeroInstance * hero,
|
||||
CDestinationNodeInfo & destination,
|
||||
const PathNodeInfo & source,
|
||||
AIPathNode * dstMode,
|
||||
@ -38,7 +38,7 @@ namespace AIPathfinding
|
||||
dstMode->theNodeBefore = source.node;
|
||||
}
|
||||
|
||||
bool SummonBoatAction::isAffordableBy(const HeroPtr & hero, const AIPathNode * source) const
|
||||
bool SummonBoatAction::isAffordableBy(const CGHeroInstance * hero, const AIPathNode * source) const
|
||||
{
|
||||
#ifdef VCMI_TRACE_PATHFINDER
|
||||
logAi->trace(
|
||||
@ -52,7 +52,7 @@ namespace AIPathfinding
|
||||
return hero->mana >= source->manaCost + getManaCost(hero);
|
||||
}
|
||||
|
||||
uint32_t SummonBoatAction::getManaCost(const HeroPtr & hero) const
|
||||
uint32_t SummonBoatAction::getManaCost(const CGHeroInstance * hero) const
|
||||
{
|
||||
SpellID summonBoat = SpellID::SUMMON_BOAT;
|
||||
|
||||
|
@ -44,16 +44,16 @@ namespace AIPathfinding
|
||||
virtual Goals::TSubgoal whatToDo(const HeroPtr & hero) const override;
|
||||
|
||||
virtual void applyOnDestination(
|
||||
const HeroPtr & hero,
|
||||
const CGHeroInstance * hero,
|
||||
CDestinationNodeInfo & destination,
|
||||
const PathNodeInfo & source,
|
||||
AIPathNode * dstMode,
|
||||
const AIPathNode * srcNode) const override;
|
||||
|
||||
bool isAffordableBy(const HeroPtr & hero, const AIPathNode * source) const;
|
||||
bool isAffordableBy(const CGHeroInstance * hero, const AIPathNode * source) const;
|
||||
|
||||
private:
|
||||
uint32_t getManaCost(const HeroPtr & hero) const;
|
||||
uint32_t getManaCost(const CGHeroInstance * hero) const;
|
||||
};
|
||||
|
||||
class BuildBoatAction : public VirtualBoatAction
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
virtual Goals::TSubgoal whatToDo(const HeroPtr & hero) const = 0;
|
||||
|
||||
virtual void applyOnDestination(
|
||||
const HeroPtr & hero,
|
||||
const CGHeroInstance * hero,
|
||||
CDestinationNodeInfo & destination,
|
||||
const PathNodeInfo & source,
|
||||
AIPathNode * dstMode,
|
||||
|
@ -122,7 +122,7 @@ namespace AIPathfinding
|
||||
}
|
||||
|
||||
auto hero = nodeStorage->getHero();
|
||||
auto danger = evaluateDanger(destination.coord, hero);
|
||||
auto danger = evaluateDanger(destination.coord, hero, cb);
|
||||
|
||||
destination.node = battleNode;
|
||||
nodeStorage->commit(destination, source);
|
||||
|
Loading…
x
Reference in New Issue
Block a user