- 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) {
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();
int unitFactionIndex = unit->getFactionIndex();
@ -1095,9 +1103,16 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
doAStarPathSearch(nodeLimitReached, whileLoopCount, unitFactionIndex,
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?
if(nodeLimitReached == true) {
unit->incrementPathfindFailedConsecutiveFrameCount();
}
else {
unit->resetPathfindFailedConsecutiveFrameCount();
}
if(nodeLimitReached == true && maxNodeCount != pathFindNodesAbsoluteMax) {
if(unit->isLastPathfindFailedFrameWithinCurrentFrameTolerance() == true) {
if(frameIndex < 0) {

View File

@ -212,8 +212,9 @@ private:
bool result = false;
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());
// if(iterFind1 != factions[unit->getFactionIndex()].mapFromToNodeList.end()) {
int unitFactionIndex = unit->getFactionIndex();
// 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);
// if(iterFind2 != iterFind1->second.end()) {
// 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->aproxCanMoveSoon(unit, node->pos, sucPos);
if(openPos(sucPos, factions[unit->getFactionIndex()]) == false &&
if(openPos(sucPos, factions[unitFactionIndex]) == false &&
canUnitMoveSoon(unit, node->pos, sucPos) == true) {
//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) {
sucNode->pos= sucPos;
sucNode->heuristic= heuristic(sucNode->pos, finalPos);
sucNode->prev= node;
sucNode->next= NULL;
sucNode->exploredCell= map->getSurfaceCell(Map::toSurfCoords(sucPos))->isExplored(unit->getTeam());
if(factions[unit->getFactionIndex()].openNodesList.find(sucNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) {
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].clear();
if(factions[unitFactionIndex].openNodesList.find(sucNode->heuristic) == factions[unitFactionIndex].openNodesList.end()) {
factions[unitFactionIndex].openNodesList[sucNode->heuristic].clear();
//factions[unitFactionIndex].openNodesList[sucNode->heuristic].reserve(PathFinder::pathFindNodesMax);
}
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].push_back(sucNode);
factions[unit->getFactionIndex()].openPosList[sucNode->pos] = true;
factions[unitFactionIndex].openNodesList[sucNode->heuristic].push_back(sucNode);
factions[unitFactionIndex].openPosList[sucNode->pos] = 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;
}
@ -307,14 +309,20 @@ private:
int & unitFactionIndex, bool & pathFound, Node *& node, const Vec2i & finalPos,
const bool tryJPSPathfinder, std::map<Vec2i,bool> closedNodes,
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) {
whileLoopCount++;
if(factions[unitFactionIndex].openNodesList.empty() == true) {
if(factionState.openNodesList.empty() == true) {
pathFound = false;
break;
}
node = minHeuristicFastLookup(factions[unitFactionIndex]);
node = minHeuristicFastLookup(factionState);
if(node->pos == finalPos || node->exploredCell == false) {
pathFound = true;
break;
@ -322,58 +330,54 @@ private:
if(tryJPSPathfinder == true) {
closedNodes[node->pos] = true;
}
if(factions[unitFactionIndex].closedNodesList.find(node->heuristic) == factions[unitFactionIndex].closedNodesList.end()) {
factions[unitFactionIndex].closedNodesList[node->heuristic].clear();
if(factionState.closedNodesList.find(node->heuristic) == factionState.closedNodesList.end()) {
factionState.closedNodesList[node->heuristic].clear();
//factionState.closedNodesList[node->heuristic].reserve(PathFinder::pathFindNodesMax);
}
factions[unitFactionIndex].closedNodesList[node->heuristic].push_back(node);
factions[unitFactionIndex].openPosList[node->pos] = true;
factionState.closedNodesList[node->heuristic].push_back(node);
factionState.openPosList[node->pos] = true;
if(tryJPSPathfinder == true) {
astarJPS(cameFrom, node, finalPos, closedNodes, canAddNode, unit, nodeLimitReached, maxNodeCount);
}
else {
int failureCount = 0;
int cellCount = 0;
int tryDirection = factions[unitFactionIndex].random.randRange(0, 3);
if(tryDirection == 3){
for(int i = 1;i >= -1 && nodeLimitReached == false;--i){
for(int j = -1;j <= 1 && nodeLimitReached == false;++j){
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false){
int failureCount = 0;
int cellCount = 0;
int tryDirection = factionState.random.randRange(0, 3);
if(tryDirection == 3) {
for(int i = 1;i >= -1 && nodeLimitReached == false;--i) {
for(int j = -1;j <= 1 && nodeLimitReached == false;++j) {
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
failureCount++;
}
cellCount++;
}
}
}
else if(tryDirection == 2) {
for(int i = -1;i <= 1 && nodeLimitReached == false;++i){
for(int j = 1;j >= -1 && nodeLimitReached == false;--j){
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false){
for(int i = -1;i <= 1 && nodeLimitReached == false;++i) {
for(int j = 1;j >= -1 && nodeLimitReached == false;--j) {
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
failureCount++;
}
cellCount++;
}
}
}
else if(tryDirection == 1) {
for(int i = -1;i <= 1 && nodeLimitReached == false;++i){
for(int j = -1;j <= 1 && nodeLimitReached == false;++j){
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false){
failureCount++;
}
cellCount++;
for(int i = -1;i <= 1 && nodeLimitReached == false;++i) {
for(int j = -1;j <= 1 && nodeLimitReached == false;++j) {
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
failureCount++;
}
cellCount++;
}
}
else{
for(int i = 1;i >= -1 && nodeLimitReached == false;--i){
for(int j = 1;j >= -1 && nodeLimitReached == false;--j){
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false){
}
else {
for(int i = 1;i >= -1 && nodeLimitReached == false;--i) {
for(int j = 1;j >= -1 && nodeLimitReached == false;--j) {
if(processNode(unit, node, finalPos, i, j, nodeLimitReached, maxNodeCount) == false) {
failureCount++;
}
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;
lastAttackedUnitId = -1;
causeOfDeath = ucodNone;
pathfindFailedConsecutiveFrameCount = 0;
targetRotationZ=.0f;
targetRotationX=.0f;
@ -3772,6 +3773,9 @@ void Unit::saveGame(XmlNode *rootNode) {
unitNode->addAttribute("lastAttackedUnitId",intToStr(lastAttackedUnitId), mapTagReplacements);
// CauseOfDeathType causeOfDeath;
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) {
@ -4177,6 +4181,8 @@ Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction *
// CauseOfDeathType causeOfDeath;
result->causeOfDeath = static_cast<CauseOfDeathType>(unitNode->getAttribute("causeOfDeath")->getIntValue());
result->pathfindFailedConsecutiveFrameCount = unitNode->getAttribute("pathfindFailedConsecutiveFrameCount")->getIntValue();
if(result->alive) {
world->getMapPtr()->putUnitCells(result, newUnitPos);
//result->born();

View File

@ -436,6 +436,8 @@ private:
int lastAttackedUnitId;
CauseOfDeathType causeOfDeath;
uint32 pathfindFailedConsecutiveFrameCount;
public:
Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing);
~Unit();
@ -448,6 +450,10 @@ public:
const UnitAttackBoostEffectOriginator & getAttackBoostOriginatorEffect() const { return currentAttackBoostOriginatorEffect; }
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
Command *getCurrrentCommandThreadSafe();
void setIgnoreCheckCommand(bool value) { ignoreCheckCommand=value;}