From 3d482ca366b85d6ab7d665e02e8f8b443852950c Mon Sep 17 00:00:00 2001 From: James McCulloch Date: Sun, 8 Aug 2010 04:43:24 +0000 Subject: [PATCH] * fix (work-around) for apparent MSVC bug, in AStarNode::operator<() * removed some unused pathfinder stuff, and const-ified some other stuff * RoutePlanner is used in scenarios (for testing purposes...) --- source/glest_game/ai/cartographer.cpp | 11 - source/glest_game/ai/cartographer.h | 6 - source/glest_game/ai/node_map.cpp | 291 ------------------ source/glest_game/ai/node_map.h | 185 ----------- source/glest_game/ai/node_pool.cpp | 5 +- source/glest_game/ai/node_pool.h | 35 ++- source/glest_game/ai/route_planner.cpp | 8 +- source/glest_game/ai/route_planner.h | 33 ++ source/glest_game/ai/search_engine.h | 2 - source/glest_game/ai/search_functions.inl | 155 ---------- source/glest_game/game/game.cpp | 2 + .../glest_game/menu/menu_state_scenario.cpp | 1 + 12 files changed, 61 insertions(+), 673 deletions(-) delete mode 100644 source/glest_game/ai/node_map.cpp delete mode 100644 source/glest_game/ai/node_map.h delete mode 100644 source/glest_game/ai/search_functions.inl diff --git a/source/glest_game/ai/cartographer.cpp b/source/glest_game/ai/cartographer.cpp index fe197833..f8e7d3a0 100644 --- a/source/glest_game/ai/cartographer.cpp +++ b/source/glest_game/ai/cartographer.cpp @@ -12,7 +12,6 @@ #include "cartographer.h" #include "game_constants.h" #include "route_planner.h" -#include "node_map.h" #include "pos_iterator.h" @@ -45,14 +44,6 @@ Cartographer::Cartographer(World *world) int w = cellMap->getW(), h = cellMap->getH(); routePlanner = world->getRoutePlanner(); - - nodeMap = new NodeMap(cellMap); - GridNeighbours gNeighbours(w, h); - nmSearchEngine = new SearchEngine(gNeighbours, nodeMap, true); - nmSearchEngine->setStorage(nodeMap); - nmSearchEngine->setInvalidKey(Vec2i(-1)); - nmSearchEngine->getNeighbourFunc().setSearchSpace(ssCellMap); - masterMap = new AnnotatedMap(world); clusterMap = new ClusterMap(masterMap, this); @@ -104,10 +95,8 @@ Cartographer::Cartographer(World *world) /** Destruct */ Cartographer::~Cartographer() { - delete nodeMap; delete masterMap; delete clusterMap; - delete nmSearchEngine; // Goal Maps deleteMapValues(resourceMaps.begin(), resourceMaps.end()); diff --git a/source/glest_game/ai/cartographer.h b/source/glest_game/ai/cartographer.h index 83256bd0..53c44fe7 100644 --- a/source/glest_game/ai/cartographer.h +++ b/source/glest_game/ai/cartographer.h @@ -15,7 +15,6 @@ #include "game_constants.h" #include "influence_map.h" #include "annotated_map.h" -#include "node_map.h" #include "cluster_map.h" #include "world.h" @@ -106,10 +105,6 @@ private: StoreMaps storeMaps; /**< goal maps for resource stores */ SiteMaps siteMaps; /**< goal maps for building sites */ - // A* stuff - NodeMap *nodeMap; - SearchEngine *nmSearchEngine; - World *world; Map *cellMap; RoutePlanner *routePlanner; @@ -135,7 +130,6 @@ public: Cartographer(World *world); virtual ~Cartographer(); - SearchEngine* getSearchEngine() { return nmSearchEngine; } RoutePlanner* getRoutePlanner() { return routePlanner; } /** Update the annotated maps when an obstacle has been added or removed from the map. diff --git a/source/glest_game/ai/node_map.cpp b/source/glest_game/ai/node_map.cpp deleted file mode 100644 index 6908e4ac..00000000 --- a/source/glest_game/ai/node_map.cpp +++ /dev/null @@ -1,291 +0,0 @@ -// ============================================================== -// This file is part of Glest (www.glest.org) -// -// Copyright (C) 2009 James McCulloch -// -// You can redistribute this code and/or modify it under -// the terms of the GNU General Public License as published -// by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version -// ============================================================== - -#include - -#include "node_map.h" -#include "annotated_map.h" // iterator typedefs - -namespace Glest { namespace Game { - -/** Construct a NodeMap */ -NodeMap::NodeMap(Map *map) - : cellMap(map) - , nodeLimit(-1) - , searchCounter(1) - , nodeCount(0) - , openTop(-1) { - invalidPos.x = invalidPos.y = 65535; - assert(!invalidPos.valid()); - bestH = invalidPos; - stride = cellMap->getW(); - nodeMap.init(cellMap->getW(), cellMap->getH()); -} - -/** resets the NodeMap for use */ -void NodeMap::reset() { - bestH = invalidPos; - searchCounter += 2; - nodeLimit = -1; - nodeCount = 0; - openTop = Vec2i(-1); -#if _GAE_DEBUG_EDITION_ - listedNodes.clear(); -#endif -} - -/** get the best candidate from the open list, and close it. - * @return the lowest estimate node from the open list, or -1,-1 if open list empty */ -Vec2i NodeMap::getBestCandidate() { - if (openTop.x < 0) { - return Vec2i(-1); // empty - } - assert(nodeMap[openTop].mark == searchCounter); - nodeMap[openTop].mark++; // set pos closed - Vec2i ret = openTop; - // set new openTop... - if (nodeMap[openTop].nextOpen.valid()) { - openTop = nodeMap[openTop].nextOpen; - } else { - openTop.x = -1; - } - return ret; -} - -/** marks an unvisited position as open - * @param pos the position to open - * @param prev the best known path to pos is from - * @param h the heuristic for pos - * @param d the costSoFar for pos - * @return true if added, false if node limit reached - */ -bool NodeMap::setOpen(const Vec2i &pos, const Vec2i &prev, float h, float d) { - assert(nodeMap[pos].mark < searchCounter); - if (nodeCount == nodeLimit) { - return false; - } - nodeMap[pos].prevNode = prev; - nodeMap[pos].mark = searchCounter; - nodeMap[pos].heuristic = h; - nodeMap[pos].distToHere = d; - float est = h + d; - nodeCount ++; - -# if _GAE_DEBUG_EDITION_ - listedNodes.push_back ( pos ); -# endif - - if (!bestH.valid() || nodeMap[pos].heuristic < nodeMap[bestH].heuristic) { - bestH = pos; - } - if (openTop.x == -1) { // top - openTop = pos; - nodeMap[pos].nextOpen = invalidPos; - return true; - } - PackedPos prevOpen, looking = openTop; - // find insert spot... - while (true) { - assert(looking.x != 255); - assert(isOpen(looking)); - - if (est < nodeMap[looking].estimate()) { - // pos better than looking, insert before 'looking' - nodeMap[pos].nextOpen = looking; - if (openTop == looking) { - openTop = pos; - } else { - assert(nodeMap[prevOpen].nextOpen == looking); - assert(prevOpen.valid()); - nodeMap[prevOpen].nextOpen = pos; - } - break; - } else { // est >= nodeMap[looking].estimate() - if (nodeMap[looking].nextOpen.valid()) { - prevOpen = looking; - looking = nodeMap[looking].nextOpen; - } else { // end of list - // insert after nodeMap[looking], set nextOpen - 1 - nodeMap[looking].nextOpen = pos; - nodeMap[pos].nextOpen = invalidPos; - break; - } - } - } // while - return true; -} -/** conditionally update a node on the open list. Tests if a path through a new nieghbour - * is better than the existing known best path to pos, updates if so. - * @param pos the open postion to test - * @param prev the new path from - * @param d the distance to here through prev - */ -void NodeMap::updateOpen(const Vec2i &pos, const Vec2i &prev, const float d) { - const float dist = nodeMap[prev].distToHere + d; - if (dist < nodeMap[pos].distToHere) { - //LOG ("Updating open node."); - nodeMap[pos].distToHere = dist; - nodeMap[pos].prevNode = prev; - const float est = nodeMap[pos].estimate(); - - if (pos == openTop) { // is top of open list anyway - //LOG("was already top"); - return; - } - PackedPos oldNext = nodeMap[pos].nextOpen; - if (est < nodeMap[openTop].estimate()) { - nodeMap[pos].nextOpen = openTop; - openTop = pos; - PackedPos ptmp, tmp = nodeMap[pos].nextOpen; - while (pos != tmp) { - assert(nodeMap[tmp].nextOpen.valid()); - ptmp = tmp; - tmp = nodeMap[tmp].nextOpen; - } - nodeMap[ptmp].nextOpen = oldNext; - //LOG ( "moved to top" ); - return; - } - PackedPos ptmp = openTop, tmp = nodeMap[openTop].nextOpen; - while (true) { - if (pos == tmp) { // no move needed - //LOG("was not moved"); - return; - } - if (est < nodeMap[tmp].estimate()) { - nodeMap[pos].nextOpen = tmp; - nodeMap[ptmp].nextOpen = pos; - while (pos != tmp) { - assert(nodeMap[tmp].nextOpen.valid()); - ptmp = tmp; - tmp = nodeMap[tmp].nextOpen; - } - //LOG("was moved up"); - nodeMap[ptmp].nextOpen = oldNext; - return; - } - ptmp = tmp; - assert(nodeMap[tmp].nextOpen.valid()); - tmp = nodeMap[tmp].nextOpen; - } - throw runtime_error("SearchMap::updateOpen() called with non-open position"); - } -} - -#define LOG(x) {} // {std::cout << x << endl;} - -void NodeMap::logOpen() { - if (openTop == Vec2i(-1)) { - LOG("Open list is empty."); - return; - } - static char buffer[4096]; - char *ptr = buffer; - PackedPos p = openTop; - while (p.valid()) { - ptr += sprintf(ptr, "%d,%d", p.x, p.y); - if (nodeMap[p].nextOpen.valid()) { - ptr += sprintf(ptr, " => "); - if (ptr - buffer > 4000) { - sprintf(ptr, " => plus more . . ."); - break; - } - } - p = nodeMap[p].nextOpen; - } - LOG(buffer); -} - -bool NodeMap::assertOpen() { - PackedPos cp; - set seen; - if (openTop.x == -1) { - return true; - } - // iterate over list, build 'seen' set, checking nextOpen is not there already - cp = openTop; - while (cp.valid()) { - seen.insert(cp); - if (seen.find(nodeMap[cp].nextOpen) != seen.end()) { - LOG("BIG TIME ERROR: open list is cyclic."); - return false; - } - cp = nodeMap[cp].nextOpen; - } - // scan entire grid, check that all nodes marked open are indeed on the open list... - set valid; - for (int y=0; y < cellMap->getH(); ++y) { - for (int x=0; x < cellMap->getW(); ++x) { - Vec2i pos(x, y); - if (isOpen(pos)) { - if (seen.find(pos) == seen.end()) { - LOG("ERROR: open list missing open node, or non open node claiming to be open."); - return false; - } - valid.insert(pos); - } - } - } - // ... and that all nodes on the list are marked open - for (set::iterator it = seen.begin(); it != seen.end(); ++it) { - if (valid.find(*it) == valid.end()) { - LOG("ERROR: node on open list was not marked open"); - return false; - } - } - return true; -} - -bool NodeMap::assertValidPath(list &path) { - if (path.size() < 2) return true; - VLIt it = path.begin(); - Vec2i prevPos = *it; - for (++it; it != path.end(); ++it) { - if (prevPos.dist(*it) < 0.99f || prevPos.dist(*it) > 1.42f) { - return false; - } - prevPos = *it; - } - return true; -} - -#if _GAE_DEBUG_EDITION_ -/* -list>* SearchMap::getLocalAnnotations() { - list> *ret = new list>(); - for ( map::iterator it = localAnnt.begin(); it != localAnnt.end(); ++ it ) { - ret->push_back(pair(it->first,nodeMap[it->first].getClearance(Field::LAND))); - } - return ret; -} -*/ - -list* NodeMap::getOpenNodes() { - list *ret = new list(); - list::iterator it = listedNodes.begin(); - for ( ; it != listedNodes.end(); ++it ) { - if ( nodeMap[*it].mark == searchCounter ) ret->push_back(*it); - } - return ret; -} - -list* NodeMap::getClosedNodes() { - list *ret = new list(); - list::iterator it = listedNodes.begin(); - for ( ; it != listedNodes.end(); ++it ) { - if ( nodeMap[*it].mark == searchCounter + 1 ) ret->push_back(*it); - } - return ret; -} - -#endif // defined ( _GAE_DEBUG_EDITION_ ) - -}} diff --git a/source/glest_game/ai/node_map.h b/source/glest_game/ai/node_map.h deleted file mode 100644 index e7647504..00000000 --- a/source/glest_game/ai/node_map.h +++ /dev/null @@ -1,185 +0,0 @@ -// ============================================================== -// This file is part of Glest (www.glest.org) -// -// Copyright (C) 2009 James McCulloch -// -// You can redistribute this code and/or modify it under -// the terms of the GNU General Public License as published -// by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version -// ============================================================== - -#ifndef _GLEST_GAME_ASTAR_NODE_MAP_H_ -#define _GLEST_GAME_ASTAR_NODE_MAP_H_ - -#include "game_constants.h" -#include "vec.h" -#include "world.h" - -namespace Glest { namespace Game { - -using Shared::Graphics::Vec2i; -using Shared::Platform::uint16; -using Shared::Platform::uint32; - -#define MAX_MAP_COORD_BITS 16 -#define MAX_MAP_COORD ((1<Node status for this search,

- *
  • mark < NodeMap::searchCounter => unvisited
  • - *
  • mark == NodeMap::searchCounter => open
  • - *
  • mark == NodeMap::searchCounter + 1 => closed
*/ - uint32 mark; - - /** best route to here is from, valid only if this node is closed */ - PackedPos prevNode; - /** 'next' node in open list, valid only if this node is open */ - PackedPos nextOpen; - /** heuristic from this cell, valid only if node visited */ - float heuristic; - /** cost to this cell, valid only if node visited */ - float distToHere; - - /** Construct NodeMapCell */ - NodeMapCell() { memset(this, 0, sizeof(*this)); } - - /** the estimate function, costToHere + heuristic */ - float estimate() { return heuristic + distToHere; } -}; - -#pragma pack(pop) - -/** Wrapper for the NodeMapCell array */ -class NodeMapCellArray { -private: - NodeMapCell *array; - int stride; -public: - NodeMapCellArray() { array = NULL; } - ~NodeMapCellArray() { delete [] array; } - - void init(int w, int h) { delete [] array; array = new NodeMapCell[w * h]; stride = w; } - - /** index by Vec2i */ - NodeMapCell& operator[] (const Vec2i &pos) { return array[pos.y * stride + pos.x]; } - /** index by PackedPos */ - NodeMapCell& operator[] (const PackedPos pos) { return array[pos.y * stride + pos.x]; } -}; - -/** A NodeStorage (template interface) compliant NodeMap. Keeps a store of nodes the size of - * the map, and embeds the open and cosed list within. Uses some memory, but goes fast. - */ -class NodeMap { -public: - NodeMap(Map *map); - - // NodeStorage template interface - // - void reset(); - /** set a maximum number of nodes to expand */ - void setMaxNodes(int limit) { nodeLimit = limit > 0 ? limit : -1; } - /** is the node at pos open */ - bool isOpen(const Vec2i &pos) { return nodeMap[pos].mark == searchCounter; } - /** is the node at pos closed */ - bool isClosed(const Vec2i &pos) { return nodeMap[pos].mark == searchCounter + 1; } - - bool setOpen(const Vec2i &pos, const Vec2i &prev, float h, float d); - void updateOpen(const Vec2i &pos, const Vec2i &prev, const float cost); - Vec2i getBestCandidate(); - /** get the best heuristic node seen this search */ - Vec2i getBestSeen() { return bestH.valid() ? Vec2i(bestH) : Vec2i(-1); } - - /** get the heuristic of the node at pos [known to be visited] */ - float getHeuristicAt(const Vec2i &pos) { return nodeMap[pos].heuristic; } - /** get the cost to the node at pos [known to be visited] */ - float getCostTo(const Vec2i &pos) { return nodeMap[pos].distToHere; } - /** get the estimate for the node at pos [known to be visited] */ - float getEstimateFor(const Vec2i &pos) { return nodeMap[pos].estimate(); } - /** get the best path to the node at pos [known to be visited] */ - Vec2i getBestTo(const Vec2i &pos) { - return nodeMap[pos].prevNode.valid() ? Vec2i(nodeMap[pos].prevNode) : Vec2i(-1); - } - -private: - /** The array of nodes */ - NodeMapCellArray nodeMap; - - Map *cellMap; - - /** The stride of the array */ - int stride; - /** The current node expansion limit */ - int nodeLimit; - /** A counter, with NodeMapCell::mark determines validity of nodes in current search */ - uint32 searchCounter, - /** Number of nodes expanded this/last search */ - nodeCount; - /** An invalid PackedPos */ - PackedPos invalidPos; - /** The lowest heuristic node seen this/last search */ - PackedPos bestH; - /** The top of the open list is at */ - Vec2i openTop; - - /** Debug */ - bool assertValidPath(list &path); - /** Debug */ - bool assertOpen(); - /** Debug */ - void logOpen(); - -#ifdef _GAE_DEBUG_EDITION_ -public: - list* getOpenNodes (); - list* getClosedNodes (); - list listedNodes; -#endif - -}; - -}} - -#endif diff --git a/source/glest_game/ai/node_pool.cpp b/source/glest_game/ai/node_pool.cpp index d3286cd4..e8042cd8 100644 --- a/source/glest_game/ai/node_pool.cpp +++ b/source/glest_game/ai/node_pool.cpp @@ -94,9 +94,10 @@ void NodePool::addOpenNode(AStarNode *node) { * is better than the existing known best path to pos, updates if so. * @param pos the open postion to test * @param prev the new path from - * @param d the distance to here through prev */ + * @param cost the cost to here from prev */ void NodePool::updateOpen(const Vec2i &pos, const Vec2i &prev, const float cost) { - //assert(isClosed(prev)); + assert(isClosed(prev)); + assert(isOpen(pos)); AStarNode *posNode, *prevNode; posNode = markerArray.get(pos); prevNode = markerArray.get(prev); diff --git a/source/glest_game/ai/node_pool.h b/source/glest_game/ai/node_pool.h index 4a4b265d..53819026 100644 --- a/source/glest_game/ai/node_pool.h +++ b/source/glest_game/ai/node_pool.h @@ -41,13 +41,13 @@ struct PosOff { /**< A bit packed position (Vec2i) and offset (direction) pai assert(pos.x <= 8191 && pos.y <= 8191); x = pos.x; y = pos.y; return *this; } - bool operator==(PosOff &p) - { return x == p.x && y == p.y; } /**< compare position components only */ - Vec2i getPos() { return Vec2i(x, y); } /**< this packed pos as Vec2i */ - Vec2i getPrev() { return Vec2i(x + ox, y + oy); } /**< return pos + offset */ - Vec2i getOffset() { return Vec2i(ox, oy); } /**< return offset */ - bool hasOffset() { return ox || oy; } /**< has an offset */ - bool valid() { return x >= 0 && y >= 0; } /**< is this position valid */ + bool operator==(PosOff &p) const + { return x == p.x && y == p.y; } /**< compare position components only */ + Vec2i getPos() const { return Vec2i(x, y); } /**< this packed pos as Vec2i */ + Vec2i getPrev() const { return Vec2i(x + ox, y + oy); } /**< return pos + offset */ + Vec2i getOffset() const { return Vec2i(ox, oy); } /**< return offset */ + bool hasOffset() const { return ox || oy; } /**< has an offset */ + bool valid() const { return x >= 0 && y >= 0; } /**< is this position valid */ int32 x : 14; /**< x coordinate */ int32 y : 14; /**< y coordinate */ @@ -65,24 +65,25 @@ struct AStarNode { /**< A node structure for A* with NodePool */ float heuristic; /**< estimate of distance to goal */ float distToHere; /**< cost from origin to this node */ - float est() const { return distToHere + heuristic;} /**< estimate, costToHere + heuristic */ - Vec2i pos() { return posOff.getPos(); } /**< position of this node */ - Vec2i prev() { return posOff.getPrev(); } /**< best path to this node is from */ - bool hasPrev() { return posOff.hasOffset(); } /**< has valid previous 'pointer' */ + float est() const { return distToHere + heuristic;} /**< estimate, costToHere + heuristic */ + Vec2i pos() const { return posOff.getPos(); } /**< position of this node */ + Vec2i prev() const { return posOff.getPrev(); } /**< best path to this node is from */ + bool hasPrev() const{ return posOff.hasOffset(); } /**< has valid previous 'pointer' */ int32 heap_ndx; void setHeapIndex(int ndx) { heap_ndx = ndx; } int getHeapIndex() const { return heap_ndx; } bool operator<(const AStarNode &that) const { - const float diff = (distToHere + heuristic) - (that.distToHere + that.heuristic); - if (diff < 0) return true; - else if (diff > 0) return false; + const float diff = est() - that.est(); + if (diff < 0.f) return true; + if (diff > 0.f) return false; // tie, prefer closer to goal... - if (heuristic < that.heuristic) return true; - if (heuristic > that.heuristic) return false; + const float h_diff = heuristic - that.heuristic; + if (h_diff < 0.f) return true; + if (h_diff > 0.f) return false; // still tied... just distinguish them somehow... - return this < &that; + return pos() < that.pos(); } }; // == 128 bits (16 bytes) #pragma pack(pop) diff --git a/source/glest_game/ai/route_planner.cpp b/source/glest_game/ai/route_planner.cpp index 7209d9bd..38376ed9 100644 --- a/source/glest_game/ai/route_planner.cpp +++ b/source/glest_game/ai/route_planner.cpp @@ -847,16 +847,16 @@ TravelState RoutePlanner::customGoalSearch(PMap1Goal &goal, Unit *unit, const Ve UnitPath &path = *advPath; WaypointPath &wpPath = *unit->getWaypointPath(); const Vec2i &start = unit->getPos(); + // setup search - MoveCost moveCost(unit->getCurrField(), unit->getType()->getSize(), world->getCartographer()->getMasterMap()); + AnnotatedMap *aMap = world->getCartographer()->getMasterMap(); + MoveCost moveCost(unit->getCurrField(), unit->getType()->getSize(), aMap); DiagonalDistance heuristic(target); nsgSearchEngine->setNodeLimit(512); nsgSearchEngine->setStart(start, heuristic(start)); - AStarResult r; - AnnotatedMap *aMap = world->getCartographer()->getMasterMap(); aMap->annotateLocal(unit); - r = nsgSearchEngine->aStar(goal, moveCost, heuristic); + AStarResult r = nsgSearchEngine->aStar(goal, moveCost, heuristic); aMap->clearLocalAnnotations(unit); PF_TRACE(); diff --git a/source/glest_game/ai/route_planner.h b/source/glest_game/ai/route_planner.h index f9f9f2cf..8b5cb8de 100644 --- a/source/glest_game/ai/route_planner.h +++ b/source/glest_game/ai/route_planner.h @@ -212,6 +212,39 @@ public: }; // class RoutePlanner +/** Diaginal Distance Heuristic */ +class DiagonalDistance { +public: + DiagonalDistance(const Vec2i &target) : target(target) {} + /** search target */ + Vec2i target; + /** The heuristic function. @param pos the position to calculate the heuristic for + * @return an estimate of the cost to target */ + float operator()(const Vec2i &pos) const { + float dx = (float)abs(pos.x - target.x), + dy = (float)abs(pos.y - target.y); + float diag = dx < dy ? dx : dy; + float straight = dx + dy - 2 * diag; + return 1.4 * diag + straight; + } +}; + +/** Goal function for 'normal' search */ +class PosGoal { +private: + Vec2i target; /**< search target */ + +public: + PosGoal(const Vec2i &target) : target(target) {} + + /** The goal function @param pos position to test + * @param costSoFar the cost of the shortest path to pos + * @return true if pos is target, else false */ + bool operator()(const Vec2i &pos, const float costSoFar) const { + return pos == target; + } +}; + //TODO: put these somewhere sensible class TransitionHeuristic { DiagonalDistance dd; diff --git a/source/glest_game/ai/search_engine.h b/source/glest_game/ai/search_engine.h index e02448e1..e386c5a3 100644 --- a/source/glest_game/ai/search_engine.h +++ b/source/glest_game/ai/search_engine.h @@ -24,8 +24,6 @@ using Shared::Graphics::Vec2i; static const float SQRT2 = Shared::Graphics::sqrt2; -#include "search_functions.inl" - enum OrdinalDir { odNorth, odNorthEast, odEast, odSouthEast, odSouth, odSouthWest, odWest, odNorthWest, odCount }; diff --git a/source/glest_game/ai/search_functions.inl b/source/glest_game/ai/search_functions.inl deleted file mode 100644 index 18923239..00000000 --- a/source/glest_game/ai/search_functions.inl +++ /dev/null @@ -1,155 +0,0 @@ -// ============================================================== -// This file is part of Glest (www.glest.org) -// -// Copyright (C) 2009 James McCulloch -// -// You can redistribute this code and/or modify it under -// the terms of the GNU General Public License as published -// by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version -// ============================================================== -// -// search_functions.inl -// -// INLINE FILE, do not place any silly namespaces or what-not in here, this -// is a part of search_engine.h -// - -/** Goal function for 'normal' search */ -class PosGoal { -private: - Vec2i target; /**< search target */ - -public: - PosGoal(const Vec2i &target) : target(target) {} - - /** The goal function @param pos position to test - * @param costSoFar the cost of the shortest path to pos - * @return true if pos is target, else false */ - bool operator()(const Vec2i &pos, const float costSoFar) const { - return pos == target; - } -}; - -/** Goal function for 'get within x of' searches */ -class RangeGoal { -private: - Vec2i target; /**< search target */ - float range; /**< range to get within */ - -public: - RangeGoal(const Vec2i &target, float range) : target(target), range(range) {} - - /** The goal function @param pos position to test - * @param costSoFar the cost of the shortest path to pos - * @return true if pos is within range of target, else false */ - bool operator()(const Vec2i &pos, const float costSoFar) const { - return pos.dist(target) <= range; - } -}; - -/** The 'No Goal' function. Just returns false. Use with care! Use Cost function to control termination - * by exhausting the open list. */ -class NoGoal { -public: - NoGoal(){} - /** The goal function @param pos the position to ignore - * @param costSoFar the cost of the shortest path to pos - * @return false */ - bool operator()(const Vec2i &pos, const float costSoFar) const { - return false; - } -}; - -/** A uniform cost function */ -class UniformCost { -private: - float cost; /**< The uniform cost to return */ - -public: - UniformCost(float cost) : cost(cost) {} - - /** The cost function @param p1 position 1 @param p2 position 2 ('adjacent' p1) - * @return cost */ - float operator()(const Vec2i &p1, const Vec2i &p2) const { return cost; } -}; - -/** distance cost, no obstacle checks */ -class DistanceCost { -public: - DistanceCost(){} - /** The cost function @param p1 position 1 @param p2 position 2 ('adjacent' p1) - * @return 1.0 if p1 and p2 are 'in line', else SQRT2 */ - float operator()(const Vec2i &p1, const Vec2i &p2) const { - assert ( p1.dist(p2) < 1.5 ); - if ( p1.x != p2.x && p1.y != p2.y ) { - return SQRT2; - } - return 1.0f; - } -}; - -/** Diaginal Distance Heuristic */ -class DiagonalDistance { -public: - DiagonalDistance(const Vec2i &target) : target(target) {} - /** search target */ - Vec2i target; - /** The heuristic function. @param pos the position to calculate the heuristic for - * @return an estimate of the cost to target */ - float operator()(const Vec2i &pos) const { - float dx = (float)abs(pos.x - target.x), - dy = (float)abs(pos.y - target.y); - float diag = dx < dy ? dx : dy; - float straight = dx + dy - 2 * diag; - return 1.4 * diag + straight; - } -}; - -/** Diagonal Distance Overestimating Heuristic */ -class OverEstimate { -private: - Vec2i target; /**< search target */ - -public: - OverEstimate(const Vec2i &target) : target(target) {} - - /** The heuristic function. @param pos the position to calculate the heuristic for - * @return an (over) estimate of the cost to target */ - float operator()(const Vec2i &pos) const { - float dx = (float)abs(pos.x - target.x), - dy = (float)abs(pos.y - target.y); - float diag = dx < dy ? dx : dy; - float estimate = 1.4 * diag + (dx + dy - 2 * diag); - estimate *= 1.25; - return estimate; - } -}; - -/** Diagonal Distance underestimating Heuristic */ -class UnderEstimate { -private: - Vec2i target; /**< search target */ - -public: - UnderEstimate(const Vec2i &target) : target(target) {} - - /** The heuristic function. @param pos the position to calculate the heuristic for - * @return an (over) estimate of the cost to target */ - float operator()(const Vec2i &pos) const { - float dx = (float)abs(pos.x - target.x), - dy = (float)abs(pos.y - target.y); - float diag = dx < dy ? dx : dy; - float estimate = 1.4 * diag + (dx + dy - 2 * diag); - estimate *= 0.75; - return estimate; - } -}; - -/** The Zero Heuristic, for doing Dijkstra searches */ -class ZeroHeuristic { -public: - ZeroHeuristic(){} - /** The 'no heuristic' function. @param pos the position to ignore @return 0.f */ - float operator()(const Vec2i &pos) const { return 0.0f; } -}; diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 2c232084..99e02236 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -478,6 +478,8 @@ void Game::init() logger.add("Launching game"); SystemFlags::OutputDebug(SystemFlags::debugSystem,"================ STARTING GAME ================\n"); + SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"================ STARTING GAME ================\n"); + SystemFlags::OutputDebug(SystemFlags::debugPathFinder,"PathFinderType: %s\n", (getGameSettings()->getPathFinderType() ? "RoutePlanner" : "PathFinder")); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } diff --git a/source/glest_game/menu/menu_state_scenario.cpp b/source/glest_game/menu/menu_state_scenario.cpp index 69d39021..a916b130 100644 --- a/source/glest_game/menu/menu_state_scenario.cpp +++ b/source/glest_game/menu/menu_state_scenario.cpp @@ -239,6 +239,7 @@ void MenuStateScenario::loadGameSettings(const ScenarioInfo *scenarioInfo, GameS gameSettings->setFactionCount(factionCount); gameSettings->setFogOfWar(scenarioInfo->fogOfWar); + gameSettings->setPathFinderType(pfRoutePlanner); } ControlType MenuStateScenario::strToControllerType(const string &str){