// ============================================================== // 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,

* */ 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