5
5
#include " SFML/Graphics.hpp"
6
6
#include " Grid.hpp"
7
7
#include " GridCellStates.hpp"
8
+ #include < vector>
9
+ #include < unordered_set>
8
10
9
11
using namespace std ;
10
12
using namespace sf ;
@@ -18,7 +20,16 @@ class PathFinder
18
20
// node for each grid position
19
21
struct GridNode
20
22
{
21
- GridValue val;
23
+ GridValue val; // value of this node
24
+ Vector2i gridPos; // position of this node in the grid
25
+ GridNode *parentNode; // node that came before this node in the path
26
+ int gCost ; // distance from starting node
27
+ int hCost; // distance from end node
28
+
29
+ int fCost ()
30
+ {
31
+ return gCost + hCost;
32
+ }
22
33
};
23
34
24
35
private:
@@ -29,6 +40,17 @@ class PathFinder
29
40
Vector2i* startPos;
30
41
Vector2i* endPos;
31
42
43
+ // custom hashing for GridNodes
44
+ struct NodeHash
45
+ {
46
+ size_t operator ()(const GridNode& node) const
47
+ {
48
+ return node.gCost + node.hCost + (int )node.val ;
49
+ }
50
+ };
51
+
52
+ int getDistance (GridNode* node1, GridNode* node2);
53
+
32
54
public:
33
55
PathFinder (int width, int height, int cellSize);
34
56
@@ -44,6 +66,8 @@ class PathFinder
44
66
45
67
bool setValAt (Vector2i pos, GridValue val);
46
68
69
+ GridNode* getShortestPath ();
70
+
47
71
private:
48
72
void initializeNodes ();
49
73
@@ -58,7 +82,9 @@ void PathFinder::initializeNodes()
58
82
{
59
83
for (int y = 0 ; y < grid->getGridHeight (); y++)
60
84
{
61
- grid->setValAt (x, y, new GridNode ());
85
+ GridNode* newNode = new GridNode ();
86
+ newNode->gridPos = Vector2i (x, y);
87
+ grid->setValAt (x, y, newNode);
62
88
}
63
89
}
64
90
}
@@ -246,6 +272,67 @@ bool PathFinder::setValAt(Vector2i pos, GridValue val)
246
272
return setValAt (gridPos.x , gridPos.y , val);
247
273
}
248
274
275
+ int PathFinder::getDistance (GridNode* node1, GridNode* node2)
276
+ {
277
+ int xDist = abs (node1->gridPos .x - node2->gridPos .x );
278
+ int yDist = abs (node1->gridPos .y - node2->gridPos .y );
279
+
280
+ int numOfDiagonals = min (xDist, yDist);
281
+ int numOfRegMoves = abs (xDist - yDist);
282
+ }
283
+
284
+ PathFinder::GridNode* PathFinder::getShortestPath ()
285
+ {
286
+ GridNode* startNode = grid->getValueAt (startPos->x , startPos->y );
287
+ GridNode* endNode = grid->getValueAt (endPos->x , endPos->y );
288
+
289
+ vector<GridNode*> openList;
290
+ unordered_set<GridNode*, NodeHash> closedSet;
291
+
292
+ openList.push_back (startNode);
293
+
294
+ while (openList.size () > 0 )
295
+ {
296
+ // find node with lowest fcost or lowest hcost if fcost are the same
297
+ GridNode* lowestCostNode = openList[0 ];
298
+ int pos = 0 ;
299
+ for (int i = 1 ; i < openList.size (); i++)
300
+ {
301
+ GridNode* currNode = openList[i];
302
+ if (currNode->fCost () < lowestCostNode->fCost ()
303
+ || (currNode->fCost () == lowestCostNode->fCost ()
304
+ && currNode->hCost <= lowestCostNode->hCost ))
305
+ {
306
+ lowestCostNode = currNode;
307
+ pos = i;
308
+ }
309
+ }
310
+
311
+ // remove lowest cost node from open list
312
+ vector<GridNode*>::iterator it = openList.begin () + pos;
313
+ openList.erase (it);
314
+ // add lowest cost node to closed set
315
+ closedSet.insert (lowestCostNode);
316
+
317
+ Vector2i lowestCostPos = lowestCostNode->gridPos ;
318
+ vector<GridNode*>* neighbours = grid->getNeighbours (lowestCostPos.x , lowestCostPos.y );
319
+ for (int i = 0 ; i < neighbours->size (); i++)
320
+ {
321
+ GridNode* currNode = (*neighbours)[i];
322
+
323
+ if (currNode->val == GridValue::OCCUPIED
324
+ || closedSet.find (currNode) != closedSet.end ())
325
+ {
326
+ // go to next neighbour if this node is either occupied
327
+ // or is in the closed set
328
+ continue ;
329
+ }
330
+
331
+
332
+ }
333
+
334
+ }
335
+ }
249
336
250
337
251
338
#endif // !PATH_FINDER_H
0 commit comments