00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "global.hpp"
00017 #include "astarnode.hpp"
00018
00019 #include <cassert>
00020
00021 void a_star_node::initNode(gamemap::location const &pos, gamemap::location const &dst,
00022 double cost, a_star_node *parent, std::set<gamemap::location> const *teleports)
00023 {
00024 isInCloseList = false;
00025 loc = pos;
00026 nodeParent = parent;
00027 g = cost;
00028 h = heuristic(pos, dst);
00029
00030 if (teleports != NULL) {
00031 double srch = h, dsth = h;
00032 std::set<gamemap::location>::const_iterator i;
00033 for(i = teleports->begin(); i != teleports->end(); ++i) {
00034 const double new_srch = heuristic(pos, *i);
00035 const double new_dsth = heuristic(*i, dst);
00036 if(new_srch < srch) {
00037 srch = new_srch;
00038 }
00039 if(new_dsth < dsth) {
00040 dsth = new_dsth;
00041 }
00042 }
00043 if(srch + dsth + 1.0 < h) {
00044 h = srch + dsth + 1.0;
00045 }
00046 }
00047 }
00048
00049 class a_star_world::poss_a_star_node
00050 {
00051 private:
00052 typedef std::vector<a_star_node*> vect_page_a_star_node;
00053 vect_page_a_star_node vectPageAStarNode_;
00054 size_t nbElemByPage_;
00055 size_t capacity_;
00056 size_t curIndex_;
00057 void addPage();
00058
00059 public:
00060 poss_a_star_node();
00061 ~poss_a_star_node();
00062 a_star_node *getAStarNode();
00063 void clear();
00064 };
00065
00066 void a_star_world::poss_a_star_node::addPage()
00067 {
00068 vectPageAStarNode_.push_back(new a_star_node[nbElemByPage_]);
00069 capacity_ += nbElemByPage_;
00070 }
00071
00072 a_star_world::poss_a_star_node::poss_a_star_node()
00073 : capacity_(0), curIndex_(0)
00074 {
00075 nbElemByPage_ = size_t((4096 - 24) / sizeof(a_star_node));
00076 assert(nbElemByPage_ > 0);
00077 addPage();
00078 }
00079
00080 a_star_world::poss_a_star_node::~poss_a_star_node()
00081 {
00082 for(vect_page_a_star_node::iterator iter = vectPageAStarNode_.begin(),
00083 iend = vectPageAStarNode_.end();
00084 iter != iend; ++iter)
00085 delete[] *iter;
00086 }
00087
00088 a_star_node *a_star_world::poss_a_star_node::getAStarNode()
00089 {
00090
00091 assert(capacity_ > 0);
00092 assert(curIndex_ <= capacity_);
00093
00094 if (curIndex_ == capacity_)
00095 addPage();
00096 size_t i = curIndex_++;
00097 return &vectPageAStarNode_[i / nbElemByPage_][i % nbElemByPage_];
00098 }
00099
00100 void a_star_world::poss_a_star_node::clear()
00101 {
00102 if (capacity_ > nbElemByPage_) {
00103 for(vect_page_a_star_node::iterator iter = vectPageAStarNode_.begin() + 1,
00104 iend = vectPageAStarNode_.end();
00105 iter != iend; ++iter)
00106 delete[] *iter;
00107 vectPageAStarNode_.resize(1);
00108 capacity_ = nbElemByPage_;
00109 }
00110 curIndex_ = 0;
00111
00112 assert(capacity_ == nbElemByPage_);
00113 assert(vectPageAStarNode_.size() == 1);
00114
00115 }
00116
00117 a_star_world::a_star_world()
00118 : pool_(new poss_a_star_node), width_(0), nbNode_(0)
00119 {
00120 }
00121
00122 a_star_world::~a_star_world()
00123 {
00124 delete pool_;
00125 }
00126
00127 void a_star_world::resize_IFN(size_t parWidth, size_t parHeight)
00128 {
00129
00130 assert(nbNode_ == 0);
00131
00132 width_ = parWidth;
00133 size_t sz = parWidth * parHeight;
00134 if (vectAStarNode_.size() == sz)
00135 return;
00136 vectAStarNode_.reserve(sz);
00137 vectAStarNode_.resize(sz);
00138 }
00139
00140 void a_star_world::clear(void)
00141 {
00142 a_star_node *locNode = NULL;
00143 std::fill(vectAStarNode_.begin(), vectAStarNode_.end(), locNode);
00144 nbNode_ = 0;
00145 pool_->clear();
00146 }
00147
00148 a_star_node *a_star_world::getNodeFromLocation(gamemap::location const &loc, bool &isCreated)
00149 {
00150
00151 assert(loc.valid());
00152 assert(loc.x + loc.y * width_ < vectAStarNode_.size());
00153
00154
00155 a_star_node *&node = vectAStarNode_[loc.x + loc.y * width_];
00156 if ((isCreated = (node == NULL))) {
00157 node = pool_->getAStarNode();
00158 ++nbNode_;
00159 }
00160 return node;
00161 }