* added DebugType debugPathFinder

This commit is contained in:
James McCulloch 2010-07-24 11:43:03 +00:00
parent 1ef403c7b6
commit e73324d317
5 changed files with 156 additions and 24 deletions

View File

@ -20,6 +20,15 @@
#include "unit_type.h"
#include "leak_dumper.h"
#include <iostream>
#define PF_DEBUG(x) { \
stringstream _ss; \
_ss << x << endl; \
SystemFlags::OutputDebug(SystemFlags::debugPathFinder, _ss.str().c_str()); \
}
//#define PF_DEBUG(x) std::cout << x << endl
#if _GAE_DEBUG_EDITION_
# include "debug_renderer.h"
@ -169,11 +178,36 @@ bool RoutePlanner::isLegalMove(Unit *unit, const Vec2i &pos2) const {
return true;
}
string log_prelude(World *w, Unit *u) {
stringstream ss;
ss << "Frame: " << w->getFrameCount() << ", Unit: " << u->getId() << ", ";
return ss.str();
}
ostream& operator<<(ostream &stream, const list<Vec2i> &posList) {
list<Vec2i>::const_iterator itBegin = posList.begin();
list<Vec2i>::const_iterator itEnd = posList.end();
list<Vec2i>::const_iterator it = itBegin;
stream << " [ ";
for ( ; it != itEnd; ++it) {
if (it != itBegin) {
stream << ", ";
}
stream << *it;
}
stream << " ] ";
return stream;
}
TravelState RoutePlanner::findPathToResource(Unit *unit, const Vec2i &targetPos, const ResourceType *rt) {
PF_TRACE();
assert(rt && (rt->getClass() == rcTech || rt->getClass() == rcTileset));
ResourceMapKey mapKey(rt, unit->getCurrField(), unit->getType()->getSize());
PMap1Goal goal(world->getCartographer()->getResourceMap(mapKey));
PF_DEBUG(log_prelude(world, unit) << "findPathToResource() targetPos: " << targetPos
<< ", resource type: " << rt->getName());
return findPathToGoal(unit, goal, targetPos);
}
@ -181,6 +215,9 @@ TravelState RoutePlanner::findPathToStore(Unit *unit, const Unit *store) {
PF_TRACE();
Vec2i target = store->getCenteredPos();
PMap1Goal goal(world->getCartographer()->getStoreMap(store, unit));
PF_DEBUG(log_prelude(world, unit) << "findPathToStore() store: " << store->getId());
return findPathToGoal(unit, goal, target);
}
@ -189,6 +226,10 @@ TravelState RoutePlanner::findPathToBuildSite(Unit *unit, const UnitType *bType,
PF_TRACE();
PatchMap<1> *pMap = world->getCartographer()->getSiteMap(bType, bPos, bFacing, unit);
PMap1Goal goal(pMap);
PF_DEBUG(log_prelude(world, unit) << "findPathToBuildSite() " << "building type: " << bType->getName()
<< ", building pos: " << bPos << ", building facing = " << bFacing);
return findPathToGoal(unit, goal, bPos + Vec2i(bType->getSize() / 2));
}
@ -328,7 +369,7 @@ public:
return false;
}
/** returns the 'potential goal' transition closest to target, or null if no potential goals */
/** returns the best 'potential goal' transition found, or null if no potential goals */
const Transition* getBestSeen(const Vec2i &currPos, const Vec2i &target) {
const Transition *best = 0;
float distToBest = Shared::Graphics::infinity;//1e6f//numeric_limits<float>::infinity();
@ -344,7 +385,7 @@ public:
}
};
/** cost function for searching cluster map with a unexplored target */
/** cost function for searching cluster map with an unexplored target */
class UnexploredCost {
Field field;
int size;
@ -538,19 +579,40 @@ TravelState RoutePlanner::doRouteCache(Unit *unit) {
// refine path to at least 24 steps (or end of path)
if (!refinePath(unit)) {
CONSOLE_LOG( "refinePath() failed. [route cache]" )
wpPath.clear();
wpPath.clear(); // path has become invalid
break;
}
}
smoothPath(unit);
PF_DEBUG(log_prelude(world, unit) << " MOVING [route cahce hit] from " << unit->getPos()
<< " to " << unit->getTargetPos());
PF_DEBUG(log_prelude(world, unit) << "[low-level path further refined]");
if (!wpPath.empty()) {
PF_DEBUG("Waypoint Path: " << wpPath);
}
if (!path.empty()) {
PF_DEBUG("LowLevel Path: " << path);
}
// IF_DEBUG_EDITION( collectPath(unit); )
} else {
PF_DEBUG(log_prelude(world, unit) << " MOVING [route cahce hit] from " << unit->getPos()
<< " to " << unit->getTargetPos());
}
return tsMoving;
}
// path blocked, quickSearch to next waypoint...
// IF_DEBUG_EDITION( clearOpenClosed(unit->getPos(), wpPath.empty() ? path.back() : wpPath.front()); )
if (repairPath(unit) && attemptMove(unit)) {
// IF_DEBUG_EDITION( collectPath(unit); )
PF_DEBUG(log_prelude(world, unit) << " MOVING [cached path repaired] from " << unit->getPos()
<< " to " << unit->getTargetPos());
if (!wpPath.empty()) {
PF_DEBUG("Waypoint Path: " << wpPath);
}
if (!path.empty()) {
PF_DEBUG("LowLevel Path: " << path);
}
return tsMoving;
}
unit->setCurrSkill(scStop);
@ -583,11 +645,17 @@ TravelState RoutePlanner::doQuickPathSearch(Unit *unit, const Vec2i &target) {
path.pop();
if (attemptMove(unit)) {
// IF_DEBUG_EDITION( collectPath(unit); )
PF_DEBUG(log_prelude(world, unit) << " MOVING [doQuickPathSearch() Ok.] from " << unit->getPos()
<< " to " << unit->getTargetPos());
if (!path.empty()) {
PF_DEBUG("LowLevel Path: " << path);
}
return tsMoving;
}
}
path.clear();
}
PF_DEBUG(log_prelude(world, unit) << "doQuickPathSearch() : Failed.");
return tsBlocked;
}
@ -620,12 +688,18 @@ TravelState RoutePlanner::findAerialPath(Unit *unit, const Vec2i &targetPos) {
if (path.size() > 1) {
path.pop();
if (attemptMove(unit)) {
PF_DEBUG(log_prelude(world, unit) << " MOVING [aerial path search Ok.] from " << unit->getPos()
<< " to " << unit->getTargetPos());
if (!path.empty()) {
PF_DEBUG("LowLevel Path: " << path);
}
return tsMoving;
}
} else {
path.clear();
}
}
PF_DEBUG(log_prelude(world, unit) << " BLOCKED [aerial path search failed.]");
path.incBlockCount();
unit->setCurrSkill(scStop);
return tsBlocked;
@ -650,6 +724,7 @@ TravelState RoutePlanner::findPathToLocation(Unit *unit, const Vec2i &finalPos)
// if arrived (where we wanted to go)
if(finalPos == unit->getPos()) {
unit->setCurrSkill(scStop);
PF_DEBUG(log_prelude(world, unit) << "findPathToLocation() : ARRIVED [1]");
return tsArrived;
}
// route cache
@ -664,6 +739,7 @@ TravelState RoutePlanner::findPathToLocation(Unit *unit, const Vec2i &finalPos)
// if arrived (as close as we can get to it)
if (target == unit->getPos()) {
unit->setCurrSkill(scStop);
PF_DEBUG(log_prelude(world, unit) << "findPathToLocation() : ARRIVED [2]");
return tsArrived;
}
path.clear();
@ -672,6 +748,7 @@ TravelState RoutePlanner::findPathToLocation(Unit *unit, const Vec2i &finalPos)
if (unit->getCurrField() == fAir) {
return findAerialPath(unit, target);
}
PF_DEBUG(log_prelude(world, unit) << "findPathToLocation() " << "target pos: " << finalPos);
// QuickSearch if close to target
Vec2i startCluster = ClusterMap::cellToCluster(unit->getPos());
@ -681,7 +758,6 @@ TravelState RoutePlanner::findPathToLocation(Unit *unit, const Vec2i &finalPos)
return tsMoving;
}
}
PF_TRACE();
// Hierarchical Search
@ -694,28 +770,26 @@ TravelState RoutePlanner::findPathToLocation(Unit *unit, const Vec2i &finalPos)
res = findWaypointPathUnExplored(unit, target, wpPath);
}
if (res == hsrFailed) {
PF_DEBUG(log_prelude(world, unit) << "findPathToLocation() IMPOSSIBLE");
if (unit->getFaction()->getThisFaction()) {
world->getGame()->getConsole()->addLine(Lang::getInstance().get("InvalidPosition"));
//g_console.addLine("Can not reach destination.");
}
return tsImpossible;
} else if (res == hsrStartTrap) {
if (wpPath.size() < 2) {
CONSOLE_LOG( "START_TRAP" );
unit->setCurrSkill(scStop);
PF_DEBUG(log_prelude(world, unit) << "findPathToLocation() BLOCKED [START_TRAP]");
return tsBlocked;
}
}
PF_TRACE();
// IF_DEBUG_EDITION( collectWaypointPath(unit); )
//CONSOLE_LOG( "WaypointPath size : " + intToStr(wpPath.size()) )
if (wpPath.size() > 1) {
wpPath.pop();
}
assert(!wpPath.empty());
// IF_DEBUG_EDITION( clearOpenClosed(unit->getPos(), target); )
// refine path, to at least 20 steps (or end of path)
AnnotatedMap *aMap = world->getCartographer()->getMasterMap();
@ -723,15 +797,10 @@ TravelState RoutePlanner::findPathToLocation(Unit *unit, const Vec2i &finalPos)
wpPath.condense();
while (!wpPath.empty() && path.size() < 20) {
if (!refinePath(unit)) {
// if (res == hsrStartTrap) {
// CONSOLE_LOG( "refinePath failed. [START_TRAP]" )
// } else {
// CONSOLE_LOG( "refinePath failed. [fresh path]" )
// }
aMap->clearLocalAnnotations(unit);
path.incBlockCount();
//CONSOLE_LOG( " blockCount = " + intToStr(path.getBlockCount()) )
unit->setCurrSkill(scStop);
PF_DEBUG(log_prelude(world, unit) << "findPathToLocation() BLOCKED [refinePath() failed]");
return tsBlocked;
}
}
@ -739,14 +808,28 @@ TravelState RoutePlanner::findPathToLocation(Unit *unit, const Vec2i &finalPos)
aMap->clearLocalAnnotations(unit);
// IF_DEBUG_EDITION( collectPath(unit); )
if (path.empty()) {
CONSOLE_LOG( "post hierarchical search failure, path empty." );
PF_DEBUG(log_prelude(world, unit) << "findPathToLocation() : BLOCKED ... [post hierarchical search failure, path empty.]" );
unit->setCurrSkill(scStop);
return tsBlocked;
}
if (attemptMove(unit)) {
PF_DEBUG(log_prelude(world, unit) << " MOVING [Hierarchical Search Ok.] from " << unit->getPos()
<< " to " << unit->getTargetPos());
if (!wpPath.empty()) {
PF_DEBUG("Waypoint Path: " << wpPath);
}
if (!path.empty()) {
PF_DEBUG("LowLevel Path: " << path);
}
return tsMoving;
}
CONSOLE_LOG( "Hierarchical refined path blocked ? valid ?!?" )
PF_DEBUG(log_prelude(world, unit) << "findPathToLocation() : BLOCKED ... [possible invalid path?]");
if (!wpPath.empty()) {
PF_DEBUG("Waypoint Path: " << wpPath);
}
if (!path.empty()) {
PF_DEBUG("LowLevel Path: " << path);
}
unit->setCurrSkill(scStop);
path.incBlockCount();
return tsBlocked;
@ -809,6 +892,7 @@ TravelState RoutePlanner::findPathToGoal(Unit *unit, PMap1Goal &goal, const Vec2
// if at goal
if (goal(unit->getPos(), 0.f)) {
unit->setCurrSkill(scStop);
PF_DEBUG(log_prelude(world, unit) << "ARRIVED.");
return tsArrived;
}
// route chache
@ -822,8 +906,17 @@ TravelState RoutePlanner::findPathToGoal(Unit *unit, PMap1Goal &goal, const Vec2
// try customGoalSearch if close to target
if (unit->getPos().dist(target) < 50.f) {
if (customGoalSearch(goal, unit, target) == tsMoving) {
PF_DEBUG(log_prelude(world, unit) << " MOVING [customGoalSearch() Ok.] from " << unit->getPos()
<< " to " << unit->getTargetPos());
if (!wpPath.empty()) {
PF_DEBUG("Waypoint Path: " << wpPath);
}
if (!path.empty()) {
PF_DEBUG("LowLevel Path: " << path);
}
return tsMoving;
} else {
PF_DEBUG(log_prelude(world, unit) << "BLOCKED. [customGoalSearch() Failed.]");
unit->setCurrSkill(scStop);
return tsBlocked;
}
@ -833,8 +926,9 @@ TravelState RoutePlanner::findPathToGoal(Unit *unit, PMap1Goal &goal, const Vec2
// Hierarchical Search
tSearchEngine->reset();
if (!findWaypointPath(unit, target, wpPath)) {
PF_DEBUG(log_prelude(world, unit) << "IMPOSSIBLE.");
if (unit->getFaction()->getThisFaction()) {
CONSOLE_LOG( "Destination unreachable? [Custom Goal Search]" )
//console.add(lang.get("Unreachable"));
}
return tsImpossible;
}
@ -852,9 +946,9 @@ TravelState RoutePlanner::findPathToGoal(Unit *unit, PMap1Goal &goal, const Vec2
aMap->annotateLocal(unit);
while (!wpPath.empty() && path.size() < 20) {
if (!refinePath(unit)) {
CONSOLE_LOG( "refinePath failed! [Custom Goal Search]" )
aMap->clearLocalAnnotations(unit);
unit->setCurrSkill(scStop);
PF_DEBUG(log_prelude(world, unit) << "BLOCKED [refinePath() failed].");
return tsBlocked;
}
}
@ -862,9 +956,24 @@ TravelState RoutePlanner::findPathToGoal(Unit *unit, PMap1Goal &goal, const Vec2
aMap->clearLocalAnnotations(unit);
// IF_DEBUG_EDITION( collectPath(unit); )
if (attemptMove(unit)) {
PF_DEBUG(log_prelude(world, unit) << " MOVING [Hierarchical Search Ok.] from " << unit->getPos()
<< " to " << unit->getTargetPos());
if (!wpPath.empty()) {
PF_DEBUG("Waypoint Path: " << wpPath);
}
if (!path.empty()) {
PF_DEBUG("LowLevel Path: " << path);
}
return tsMoving;
}
PF_DEBUG(log_prelude(world, unit) << "BLOCKED [hierarchical search, possible invalid path].");
CONSOLE_LOG( "Hierarchical refined path blocked ? valid ?!? [Custom Goal Search]" )
if (!wpPath.empty()) {
PF_DEBUG("Waypoint Path: " << wpPath);
}
if (!path.empty()) {
PF_DEBUG("LowLevel Path: " << path);
}
unit->setCurrSkill(scStop);
return tsBlocked;
}

View File

@ -419,6 +419,7 @@ int glestMain(int argc, char** argv){
SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled = config.getBool("DebugPerformance","false");
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled = config.getBool("DebugWorldSynch","false");
SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled = config.getBool("DebugUnitCommands","false");
SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled = config.getBool("DebugPathFinder","false");
string debugLogFile = config.getString("DebugLogFile","");
if(getGameReadWritePath() != "") {
@ -440,20 +441,26 @@ int glestMain(int argc, char** argv){
if(debugUnitCommandsLogFile == "") {
debugUnitCommandsLogFile = debugLogFile;
}
string debugPathFinderLogFile = config.getString("DebugLogFilePathFinder","");
if(debugUnitCommandsLogFile == "") {
debugUnitCommandsLogFile = debugLogFile;
}
SystemFlags::getSystemSettingType(SystemFlags::debugSystem).debugLogFileName = debugLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).debugLogFileName = debugNetworkLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).debugLogFileName = debugPerformanceLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).debugLogFileName = debugWorldSynchLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).debugLogFileName = debugUnitCommandsLogFile;
SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).debugLogFileName = debugPathFinderLogFile;
if(haveSpecialOutputCommandLineOption == false) {
printf("Startup settings are: debugSystem [%d], debugNetwork [%d], debugPerformance [%d], debugWorldSynch [%d], debugUnitCommands[%d]\n",
printf("Startup settings are: debugSystem [%d], debugNetwork [%d], debugPerformance [%d], debugWorldSynch [%d], debugUnitCommands[%d], debugPathFinder[%d]\n",
SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled,
SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled,
SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled,
SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled,
SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled);
SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled,
SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled);
}
NetworkInterface::setDisplayMessageFunction(ExceptionHandler::DisplayMessage);
@ -468,6 +475,7 @@ int glestMain(int argc, char** argv){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"START\n");
SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"START\n");
// 256 for English
// 30000 for Chinese

View File

@ -151,6 +151,12 @@ public:
}
};
template <typename T>
std::ostream& operator<<(std::ostream &stream, const Vec2<T> &vec) {
return stream << "(" << vec.x << ", " << vec.y << ")";
}
typedef Vec2<int> Vec2i;
typedef Vec2<bool> Vec2b;
typedef Vec2<char> Vec2c;

View File

@ -40,7 +40,8 @@ public:
debugNetwork,
debugPerformance,
debugWorldSynch,
debugUnitCommands
debugUnitCommands,
debugPathFinder
};
class SystemFlagsType

View File

@ -359,14 +359,22 @@ void SystemFlags::handleDebug(DebugType type, const char *fmt, ...) {
MutexSafeWrapper safeMutex(currentDebugLog.mutex);
(*currentDebugLog.fileStream) << "[" << szBuf2 << "] " << szBuf;
if (type != debugPathFinder) {
(*currentDebugLog.fileStream) << "[" << szBuf2 << "] " << szBuf;
} else {
(*currentDebugLog.fileStream) << szBuf;
}
(*currentDebugLog.fileStream).flush();
safeMutex.ReleaseLock();
}
// output to console
else {
printf("[%s] %s", szBuf2, szBuf);
if (type != debugPathFinder) {
printf("[%s] %s", szBuf2, szBuf);
} else {
printf("%s", szBuf);
}
}
va_end(argList);