Tactics: Western Philosophers Vs. Musicians  0.12
A turn-based tactical game combining rules and gameplay elements inspired by Final Fantasy Tactics and the Mayfair Exponential Game System. Unlike most games of this type, motion is in full, grid-less 3D.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PFAStar.h
Go to the documentation of this file.
1 // Copyright (C) 2004-2011 Dylan Blair
3 //
4 // email: dblair@alumni.cs.utexas.edu
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 
21 #ifndef PF_A_STAR_H
22 #define PF_A_STAR_H
23 
24 #include "../CD_LIB/CDGrid.h"
25 
26 #include "PFConsts.h"
27 
28 namespace OpenSkyNet {
29  namespace PF {
33  struct DirOrPath {
34  bool _isDir;
37  DirOrPath() : _isDir(true), _dir(CD::NONE) {}
38  DirOrPath(CD::DIRECTION dir_) : _isDir(true), _dir(dir_) {}
39  DirOrPath(const Math::Path& path_) : _isDir(false), _dir(CD::NONE), _path(path_) {}
40  };
41 
43  struct AStarNode {
45  bool _isFromWPC;
47 #ifdef PF_USES_WPC
48  Math::Path _prevPath;
49 #endif
51  float _f,_g,_h;
52 
53  AStarNode(const Math::Point<int>& bin_) : _parent(0), _isFromWPC(false), _prevDir(CD::NONE), _bin(bin_),
55  _g(0), _h(0) {}
56 
57  inline bool operator<(const AStarNode& rhs_) const { return _f < rhs_._f; }
58  private:
59 #ifdef _WIN32
60 #pragma warning(push)
61 #pragma warning(disable:4100) //unreferenced formal parameter
62 #endif
63  AStarNode& operator=(const AStarNode& rhs_) { return *this; }
64 #ifdef _WIN32
65 #pragma warning(pop)
66 #endif
67  };
68 
70  class PriorityQueue {
71  public:
73  private:
74  std::vector<AStarNode*> _heap;
75  Utils::uint _currSize;
77 
78  inline void percolateDown(Utils::uint hole_) {
79  Utils::uint child;
80  AStarNode* tmp = _heap[hole_];
81  for ( ; (hole_ << 1) <= _currSize; hole_ = child) {
82  child = hole_ << 1;
83  if ((child != _currSize) && (*(_heap[child+1]) < *(_heap[child])))
84  child++;
85  if (*(_heap[child]) < *tmp)
86  _heap[hole_] = _heap[child];
87  else
88  break;
89  }
90  _heap[hole_] = tmp;
91  }
92  public:
93  PriorityQueue();
95 
96  inline void insert(AStarNode* node_) {
97  if (++_currSize == _heap.size())
98  _heap.resize(_currSize << 1,0);
99  int hole = 0;
100  for (hole = _currSize; (hole > 1) && (*node_ < *(_heap[hole >> 1])); hole = hole >> 1)
101  _heap[hole] = _heap[hole >> 1];
102  _heap[hole] = node_;
103  _minGCosts.add(Utils::getCompositeKey(node_->_bin)) = node_->_g;
104  }
105 
106  inline void removeMin(AStarNode*& min_) {
107  min_ = _heap[1];
108  _heap[1] = _heap[_currSize--];
109  percolateDown(1);
110  //NOTE: If I somehow flagged min_ in _minGCosts as final, which is one way
111  // to add it to a "closed set," then I could replace the addition and
112  // comparison check in processSuccessor() with this flag check.
113  }
114 
115  void init(const Math::Point<int>& bin_);
116 
117  inline bool isEmpty() const { return !_currSize; }
118 
119  inline float getMinGCost(Math::Point<int> bin_) const {
120  return _minGCosts[Utils::getCompositeKey(bin_)];
121  }
122 
123  inline void processSuccessor(AStarNode* curr_, AStarNode* successor_, const Math::Point<int>& targBin_, CD::DIRECTION prevDir_) {
124  //see note in removeMin()
125 
126  if (prevDir_ > CD::POS_Z) {
127  if (prevDir_ > CD::POS_Y_POS_Z) {
128  if ((curr_->_g + 1.73205f) < getMinGCost(successor_->_bin)) {
129  successor_->_g = curr_->_g + 1.73205f;
130  successor_->_h = sqrtf(static_cast<float>((targBin_ - successor_->_bin).getLenSqrd()));
131  successor_->_f = successor_->_g + successor_->_h;
132  successor_->_parent = curr_;
133  successor_->_prevDir = prevDir_;
134  successor_->_isFromWPC = false;
135  insert(successor_);
136  }
137  }
138  else {
139  if ((curr_->_g + 1.41421f) < getMinGCost(successor_->_bin)) {
140  successor_->_g = curr_->_g + 1.41421f;
141  successor_->_h = sqrtf(static_cast<float>((targBin_ - successor_->_bin).getLenSqrd()));
142  successor_->_f = successor_->_g + successor_->_h;
143  successor_->_parent = curr_;
144  successor_->_prevDir = prevDir_;
145  successor_->_isFromWPC = false;
146  insert(successor_);
147  }
148  }
149  }
150  else {
151  if ((curr_->_g + 1.0f) < getMinGCost(successor_->_bin)) {
152  successor_->_g = curr_->_g + 1.0f;
153  successor_->_h = sqrtf(static_cast<float>((targBin_ - successor_->_bin).getLenSqrd()));
154  successor_->_f = successor_->_g + successor_->_h;
155  successor_->_parent = curr_;
156  successor_->_prevDir = prevDir_;
157  successor_->_isFromWPC = false;
158  insert(successor_);
159  }
160  }
161  }
162 
163 #ifdef PF_USES_WPC
164  inline void processSuccessor(AStarNode* curr_, AStarNode* successor_, const Math::Point<int>& targBin_, float prevPathBinDist_) {
165  //see note in removeMin()
166 
167  float successorG = curr_->_g + prevPathBinDist_;
168  if (successorG < getMinGCost(successor_->_bin)) {
169  successor_->_g = successorG;
170  successor_->_h = sqrtf(static_cast<float>((targBin_ - successor_->_bin).getLenSqrd()));
171  successor_->_f = successor_->_g + successor_->_h;
172  successor_->_parent = curr_;
173  successor_->_isFromWPC = true;
174  insert(successor_);
175  }
176  }
177 #endif
178 
179  void getDirsOrPaths(AStarNode* curr_, std::vector<DirOrPath>& dirsOrPaths_) const;
180  };
181  }
182 }
183 
184 #endif //PF_A_STAR_H
CD::DIRECTION _prevDir
Definition: PFAStar.h:46
const Utils::uint MAX_X_DIVISIONS_FOR_ALL_GRIDS
Definition: CDGrid.h:72
AStarNode(const Math::Point< int > &bin_)
Definition: PFAStar.h:53
const Math::Point< int > & _bin
Definition: PFAStar.h:50
Definition: PFAStar.h:43
Definition: PFAStar.h:33
~PriorityQueue()
Definition: PFAStar.cpp:21
void removeMin(AStarNode *&min_)
Definition: PFAStar.h:106
User editable constants to finetune the pathfinder's capabilities.
Definition: CDGrid.h:66
float _g
Definition: PFAStar.h:51
bool operator<(const AStarNode &rhs_) const
Definition: PFAStar.h:57
float getMinGCost(Math::Point< int > bin_) const
Definition: PFAStar.h:119
bool _isFromWPC
Definition: PFAStar.h:45
Utils::uint getCompositeKey(const Math::Point< Utils::uint > &bin_)
Definition: CDGrid.h:41
CD::DIRECTION _dir
Definition: PFAStar.h:35
DIRECTION
Definition: CDGrid.h:61
Math::Path _path
Definition: PFAStar.h:36
AStarNode * _parent
Definition: PFAStar.h:44
PriorityQueue()
Definition: PFAStar.cpp:16
DirOrPath(CD::DIRECTION dir_)
Definition: PFAStar.h:38
void insert(AStarNode *node_)
Definition: PFAStar.h:96
Utils::HashTableUIntKeys< AStarNode * > _nodes
Definition: PFAStar.h:72
void processSuccessor(AStarNode *curr_, AStarNode *successor_, const Math::Point< int > &targBin_, CD::DIRECTION prevDir_)
Definition: PFAStar.h:123
void init(const Math::Point< int > &bin_)
Definition: PFAStar.cpp:32
float _h
Definition: PFAStar.h:51
DirOrPath(const Math::Path &path_)
Definition: PFAStar.h:39
float _f
Definition: PFAStar.h:51
unsigned int uint
Definition: UTypes.h:39
Definition: PFAStar.h:70
bool _isDir
Definition: PFAStar.h:34
void add(const uint &key_, const T &value_)
Definition: UHash.h:185
Definition: CDGrid.h:61
const Utils::uint MAX_Z_DIVISIONS_FOR_ALL_GRIDS
Definition: CDGrid.h:78
Definition: CDGrid.h:61
bool isEmpty() const
Definition: PFAStar.h:117
DirOrPath()
Definition: PFAStar.h:37
const Utils::uint MAX_Y_DIVISIONS_FOR_ALL_GRIDS
Definition: CDGrid.h:75
void getDirsOrPaths(AStarNode *curr_, std::vector< DirOrPath > &dirsOrPaths_) const
Definition: PFAStar.cpp:54
Definition: MPath.h:31