- attempt to tweak the pathfinder a bit for performance when units are consistently having a hard time pathfinding we scale back their max cell count used in pathfinding until they have better success in pathfinding

This commit is contained in:
Mark Vejvoda 2012-04-29 04:45:51 +00:00
parent 4ee365e1ed
commit 624237ed47
4 changed files with 80 additions and 43 deletions

View File

@ -763,7 +763,15 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
if(maxNodeCount < 0) { if(maxNodeCount < 0) {
maxNodeCount = factions[unit->getFactionIndex()].useMaxNodeCount; maxNodeCount = factions[unit->getFactionIndex()].useMaxNodeCount;
//printf("AStar set maxNodeCount = %d\n",maxNodeCount);
} }
if(maxNodeCount >= 1 && unit->getPathfindFailedConsecutiveFrameCount() >= 10) {
maxNodeCount = 200;
//printf("AStar maxpath cut for unit [%d - %s] to %d\n",unit->getId(),unit->getFullName().c_str(), maxNodeCount);
}
UnitPathInterface *path= unit->getPath(); UnitPathInterface *path= unit->getPath();
int unitFactionIndex = unit->getFactionIndex(); int unitFactionIndex = unit->getFactionIndex();
@ -1095,9 +1103,16 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
doAStarPathSearch(nodeLimitReached, whileLoopCount, unitFactionIndex, doAStarPathSearch(nodeLimitReached, whileLoopCount, unitFactionIndex,
pathFound, node, finalPos, tryJPSPathfinder, pathFound, node, finalPos, tryJPSPathfinder,
closedNodes, cameFrom, canAddNode, unit, maxNodeCount); closedNodes, cameFrom, canAddNode, unit, maxNodeCount,frameIndex);
// Now see if the unit is eligble for pathfind max nodes boost? // Now see if the unit is eligble for pathfind max nodes boost?
if(nodeLimitReached == true) {
unit->incrementPathfindFailedConsecutiveFrameCount();
}
else {
unit->resetPathfindFailedConsecutiveFrameCount();
}
if(nodeLimitReached == true && maxNodeCount != pathFindNodesAbsoluteMax) { if(nodeLimitReached == true && maxNodeCount != pathFindNodesAbsoluteMax) {
if(unit->isLastPathfindFailedFrameWithinCurrentFrameTolerance() == true) { if(unit->isLastPathfindFailedFrameWithinCurrentFrameTolerance() == true) {
if(frameIndex < 0) { if(frameIndex < 0) {

View File

@ -212,8 +212,9 @@ private:
bool result = false; bool result = false;
Vec2i sucPos= node->pos + Vec2i(i, j); Vec2i sucPos= node->pos + Vec2i(i, j);
// std::map<int, std::map<Vec2i,std::map<Vec2i, bool> > >::iterator iterFind1 = factions[unit->getFactionIndex()].mapFromToNodeList.find(unit->getType()->getId()); int unitFactionIndex = unit->getFactionIndex();
// if(iterFind1 != factions[unit->getFactionIndex()].mapFromToNodeList.end()) { // std::map<int, std::map<Vec2i,std::map<Vec2i, bool> > >::iterator iterFind1 = factions[unitFactionIndex].mapFromToNodeList.find(unit->getType()->getId());
// if(iterFind1 != factions[unitFactionIndex].mapFromToNodeList.end()) {
// std::map<Vec2i,std::map<Vec2i, bool> >::iterator iterFind2 = iterFind1->second.find(node->pos); // std::map<Vec2i,std::map<Vec2i, bool> >::iterator iterFind2 = iterFind1->second.find(node->pos);
// if(iterFind2 != iterFind1->second.end()) { // if(iterFind2 != iterFind1->second.end()) {
// std::map<Vec2i, bool>::iterator iterFind3 = iterFind2->second.find(sucPos); // std::map<Vec2i, bool>::iterator iterFind3 = iterFind2->second.find(sucPos);
@ -226,21 +227,22 @@ private:
//bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos); //bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos);
//bool canUnitMoveToCell = map->aproxCanMoveSoon(unit, node->pos, sucPos); //bool canUnitMoveToCell = map->aproxCanMoveSoon(unit, node->pos, sucPos);
if(openPos(sucPos, factions[unit->getFactionIndex()]) == false && if(openPos(sucPos, factions[unitFactionIndex]) == false &&
canUnitMoveSoon(unit, node->pos, sucPos) == true) { canUnitMoveSoon(unit, node->pos, sucPos) == true) {
//if node is not open and canMove then generate another node //if node is not open and canMove then generate another node
Node *sucNode= newNode(factions[unit->getFactionIndex()],maxNodeCount); Node *sucNode= newNode(factions[unitFactionIndex],maxNodeCount);
if(sucNode != NULL) { if(sucNode != NULL) {
sucNode->pos= sucPos; sucNode->pos= sucPos;
sucNode->heuristic= heuristic(sucNode->pos, finalPos); sucNode->heuristic= heuristic(sucNode->pos, finalPos);
sucNode->prev= node; sucNode->prev= node;
sucNode->next= NULL; sucNode->next= NULL;
sucNode->exploredCell= map->getSurfaceCell(Map::toSurfCoords(sucPos))->isExplored(unit->getTeam()); sucNode->exploredCell= map->getSurfaceCell(Map::toSurfCoords(sucPos))->isExplored(unit->getTeam());
if(factions[unit->getFactionIndex()].openNodesList.find(sucNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) { if(factions[unitFactionIndex].openNodesList.find(sucNode->heuristic) == factions[unitFactionIndex].openNodesList.end()) {
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].clear(); factions[unitFactionIndex].openNodesList[sucNode->heuristic].clear();
//factions[unitFactionIndex].openNodesList[sucNode->heuristic].reserve(PathFinder::pathFindNodesMax);
} }
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].push_back(sucNode); factions[unitFactionIndex].openNodesList[sucNode->heuristic].push_back(sucNode);
factions[unit->getFactionIndex()].openPosList[sucNode->pos] = true; factions[unitFactionIndex].openPosList[sucNode->pos] = true;
result = true; result = true;
} }
@ -249,7 +251,7 @@ private:
} }
} }
// factions[unit->getFactionIndex()].mapFromToNodeList[unit->getType()->getId()][node->pos][sucPos] = result; // factions[unitFactionIndex].mapFromToNodeList[unit->getType()->getId()][node->pos][sucPos] = result;
return result; return result;
} }
@ -307,14 +309,20 @@ private:
int & unitFactionIndex, bool & pathFound, Node *& node, const Vec2i & finalPos, int & unitFactionIndex, bool & pathFound, Node *& node, const Vec2i & finalPos,
const bool tryJPSPathfinder, std::map<Vec2i,bool> closedNodes, const bool tryJPSPathfinder, std::map<Vec2i,bool> closedNodes,
std::map<Vec2i,Vec2i> cameFrom, std::map<std::pair<Vec2i,Vec2i> , std::map<Vec2i,Vec2i> cameFrom, std::map<std::pair<Vec2i,Vec2i> ,
bool> canAddNode, Unit *& unit, int & maxNodeCount) { bool> canAddNode, Unit *& unit, int & maxNodeCount, int curFrameIndex) {
Chrono chrono;
//if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
chrono.start();
FactionState &factionState = factions[unitFactionIndex];
while(nodeLimitReached == false) { while(nodeLimitReached == false) {
whileLoopCount++; whileLoopCount++;
if(factions[unitFactionIndex].openNodesList.empty() == true) { if(factionState.openNodesList.empty() == true) {
pathFound = false; pathFound = false;
break; break;
} }
node = minHeuristicFastLookup(factions[unitFactionIndex]); node = minHeuristicFastLookup(factionState);
if(node->pos == finalPos || node->exploredCell == false) { if(node->pos == finalPos || node->exploredCell == false) {
pathFound = true; pathFound = true;
break; break;
@ -322,58 +330,54 @@ private:
if(tryJPSPathfinder == true) { if(tryJPSPathfinder == true) {
closedNodes[node->pos] = true; closedNodes[node->pos] = true;
} }
if(factions[unitFactionIndex].closedNodesList.find(node->heuristic) == factions[unitFactionIndex].closedNodesList.end()) { if(factionState.closedNodesList.find(node->heuristic) == factionState.closedNodesList.end()) {
factions[unitFactionIndex].closedNodesList[node->heuristic].clear(); factionState.closedNodesList[node->heuristic].clear();
//factionState.closedNodesList[node->heuristic].reserve(PathFinder::pathFindNodesMax);
} }
factions[unitFactionIndex].closedNodesList[node->heuristic].push_back(node); factionState.closedNodesList[node->heuristic].push_back(node);
factions[unitFactionIndex].openPosList[node->pos] = true; factionState.openPosList[node->pos] = true;
if(tryJPSPathfinder == true) { if(tryJPSPathfinder == true) {
astarJPS(cameFrom, node, finalPos, closedNodes, canAddNode, unit, nodeLimitReached, maxNodeCount); astarJPS(cameFrom, node, finalPos, closedNodes, canAddNode, unit, nodeLimitReached, maxNodeCount);
} }
else { else {
int failureCount = 0; int failureCount = 0;
int cellCount = 0; int cellCount = 0;
int tryDirection = factions[unitFactionIndex].random.randRange(0, 3); int tryDirection = factionState.random.randRange(0, 3);
if(tryDirection == 3){
for(int i = 1;i >= -1 && nodeLimitReached == false;--i){ if(tryDirection == 3) {
for(int j = -1;j <= 1 && nodeLimitReached == false;++j){ for(int i = 1;i >= -1 && nodeLimitReached == false;--i) {
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false){ for(int j = -1;j <= 1 && nodeLimitReached == false;++j) {
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
failureCount++; failureCount++;
} }
cellCount++; cellCount++;
} }
} }
} }
else if(tryDirection == 2) { else if(tryDirection == 2) {
for(int i = -1;i <= 1 && nodeLimitReached == false;++i){ for(int i = -1;i <= 1 && nodeLimitReached == false;++i) {
for(int j = 1;j >= -1 && nodeLimitReached == false;--j){ for(int j = 1;j >= -1 && nodeLimitReached == false;--j) {
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false){ if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
failureCount++; failureCount++;
} }
cellCount++; cellCount++;
} }
} }
} }
else if(tryDirection == 1) { else if(tryDirection == 1) {
for(int i = -1;i <= 1 && nodeLimitReached == false;++i){ for(int i = -1;i <= 1 && nodeLimitReached == false;++i) {
for(int j = -1;j <= 1 && nodeLimitReached == false;++j){ for(int j = -1;j <= 1 && nodeLimitReached == false;++j) {
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false){ if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
failureCount++; failureCount++;
}
cellCount++;
} }
cellCount++;
} }
} }
else{ }
for(int i = 1;i >= -1 && nodeLimitReached == false;--i){ else {
for(int j = 1;j >= -1 && nodeLimitReached == false;--j){ for(int i = 1;i >= -1 && nodeLimitReached == false;--i) {
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false){ for(int j = 1;j >= -1 && nodeLimitReached == false;--j) {
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
failureCount++; failureCount++;
} }
cellCount++; cellCount++;
@ -382,6 +386,12 @@ private:
} }
} }
} }
//!!!
//if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),nodeLimitReached,whileLoopCount,factionState.nodePoolCount);
if(chrono.getMillis() > 1) {
printf("AStar for unit [%d - %s] took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d curFrameIndex = %d travel distance = %f\n",unit->getId(),unit->getFullName().c_str(), (long long int)chrono.getMillis(),nodeLimitReached,whileLoopCount,factionState.nodePoolCount,curFrameIndex,unit->getPos().dist(finalPos));
}
} }
}; };

View File

@ -391,6 +391,7 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos,
lastAttackerUnitId = -1; lastAttackerUnitId = -1;
lastAttackedUnitId = -1; lastAttackedUnitId = -1;
causeOfDeath = ucodNone; causeOfDeath = ucodNone;
pathfindFailedConsecutiveFrameCount = 0;
targetRotationZ=.0f; targetRotationZ=.0f;
targetRotationX=.0f; targetRotationX=.0f;
@ -3772,6 +3773,9 @@ void Unit::saveGame(XmlNode *rootNode) {
unitNode->addAttribute("lastAttackedUnitId",intToStr(lastAttackedUnitId), mapTagReplacements); unitNode->addAttribute("lastAttackedUnitId",intToStr(lastAttackedUnitId), mapTagReplacements);
// CauseOfDeathType causeOfDeath; // CauseOfDeathType causeOfDeath;
unitNode->addAttribute("causeOfDeath",intToStr(causeOfDeath), mapTagReplacements); unitNode->addAttribute("causeOfDeath",intToStr(causeOfDeath), mapTagReplacements);
//pathfindFailedConsecutiveFrameCount
unitNode->addAttribute("pathfindFailedConsecutiveFrameCount",intToStr(pathfindFailedConsecutiveFrameCount), mapTagReplacements);
} }
Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction *faction, World *world) { Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction *faction, World *world) {
@ -4177,6 +4181,8 @@ Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction *
// CauseOfDeathType causeOfDeath; // CauseOfDeathType causeOfDeath;
result->causeOfDeath = static_cast<CauseOfDeathType>(unitNode->getAttribute("causeOfDeath")->getIntValue()); result->causeOfDeath = static_cast<CauseOfDeathType>(unitNode->getAttribute("causeOfDeath")->getIntValue());
result->pathfindFailedConsecutiveFrameCount = unitNode->getAttribute("pathfindFailedConsecutiveFrameCount")->getIntValue();
if(result->alive) { if(result->alive) {
world->getMapPtr()->putUnitCells(result, newUnitPos); world->getMapPtr()->putUnitCells(result, newUnitPos);
//result->born(); //result->born();

View File

@ -436,6 +436,8 @@ private:
int lastAttackedUnitId; int lastAttackedUnitId;
CauseOfDeathType causeOfDeath; CauseOfDeathType causeOfDeath;
uint32 pathfindFailedConsecutiveFrameCount;
public: public:
Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing); Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing);
~Unit(); ~Unit();
@ -448,6 +450,10 @@ public:
const UnitAttackBoostEffectOriginator & getAttackBoostOriginatorEffect() const { return currentAttackBoostOriginatorEffect; } const UnitAttackBoostEffectOriginator & getAttackBoostOriginatorEffect() const { return currentAttackBoostOriginatorEffect; }
bool unitHasAttackBoost(const AttackBoost *boost, const Unit *source) const; bool unitHasAttackBoost(const AttackBoost *boost, const Unit *source) const;
inline uint32 getPathfindFailedConsecutiveFrameCount() const { return pathfindFailedConsecutiveFrameCount; }
inline void incrementPathfindFailedConsecutiveFrameCount() { pathfindFailedConsecutiveFrameCount++; }
inline void resetPathfindFailedConsecutiveFrameCount() { pathfindFailedConsecutiveFrameCount=0; }
//queries //queries
Command *getCurrrentCommandThreadSafe(); Command *getCurrrentCommandThreadSafe();
void setIgnoreCheckCommand(bool value) { ignoreCheckCommand=value;} void setIgnoreCheckCommand(bool value) { ignoreCheckCommand=value;}