Skip to content

Commit 14981b4

Browse files
started implementing pathfinding
1 parent d501b50 commit 14981b4

File tree

2 files changed

+144
-10
lines changed

2 files changed

+144
-10
lines changed

Grid.hpp

+55-8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "GridCellStates.hpp"
66
#include "math.h"
77
#include <stdio.h>
8+
#include <vector>
89

910
using namespace std;
1011
using namespace sf;
@@ -40,10 +41,56 @@ class Grid
4041
int getGridHeight();
4142

4243
bool validCoords(int x, int y);
44+
45+
vector<T*> *getNeighbours(int x, int y);
4346

4447
~Grid();
4548
};
4649

50+
/// <summary>
51+
/// Get a list of all of the neighbouring cells around the given
52+
/// grid coordinates
53+
/// </summary>
54+
/// <param name="x">the x coordinate of a cell in the grid</param>
55+
/// <param name="y">the x coordinate of a cellin the grid</param>
56+
/// <returns>a list of all of the neighbouring cells around the given
57+
/// grid coordinates if the coordinates are valid and null otherwise</returns>
58+
template <typename T>
59+
vector<T*> *Grid<T>::getNeighbours(int x, int y)
60+
{
61+
// check for invalid coords
62+
if (!validCoords(x, y))
63+
{
64+
return NULL;
65+
}
66+
67+
// create a list to store the neighbouring cells
68+
vector<T*>* neighbours = new vector<T*>();
69+
70+
// find all neighbours around given coordinates
71+
for (int relativeX = -1; relativeX < 2; relativeX++)
72+
{
73+
for (int relativeY = -1; relativeY < 2; relativeY++)
74+
{
75+
// skip the center cell
76+
if (x == 0 && y == 0)
77+
{
78+
continue;
79+
}
80+
81+
int currX = x + relativeX;
82+
int currY = y + relativeY;
83+
// add neighbouring cell if it exists in the grid
84+
if (validCoords(currX, currY))
85+
{
86+
neighbours->push_back(getValueAt(currX, currY));
87+
}
88+
}
89+
}
90+
91+
return neighbours;
92+
}
93+
4794
/// <summary>
4895
/// Get the grid's height
4996
/// </summary>
@@ -115,8 +162,8 @@ Grid<T>::Grid(int width, int height, int cellSize)
115162
/// <summary>
116163
/// Get the value at the given grid coordinates
117164
/// </summary>
118-
/// <param name="x">the row cooridnate</param>
119-
/// <param name="y">the column coordinate</param>
165+
/// <param name="relativeX">the row cooridnate</param>
166+
/// <param name="relativeY">the column coordinate</param>
120167
/// <returns>if the coordinates are valid, returns the value at the given grid
121168
/// coordinates, and returns false otherwise</returns>
122169
template <typename T>
@@ -133,8 +180,8 @@ T *Grid<T>::getValueAt(int x, int y)
133180
/// <summary>
134181
/// Convert the grid position to a screen position
135182
/// </summary>
136-
/// <param name="x">the x coordinate of the desired grid space</param>
137-
/// <param name="y">the y coordinate of the dedired grid space</param>
183+
/// <param name="relativeX">the relativeX coordinate of the desired grid space</param>
184+
/// <param name="relativeY">the relativeY coordinate of the dedired grid space</param>
138185
/// <returns>a screen position in pixels as a Vector2f of the given cell
139186
/// in the grid if the given coordinates are valid, otherwise returns NULL</returns>
140187
template <typename T>
@@ -163,8 +210,8 @@ Vector2i Grid<T>::screenToGrid(Vector2i pos)
163210
/// <summary>
164211
/// Check to see if the given grid coordinates are valid
165212
/// </summary>
166-
/// <param name="x">the x coordinate of the desired cell</param>
167-
/// <param name="y"the y coordinate of the desired cell></param>
213+
/// <param name="relativeX">the relativeX coordinate of the desired cell</param>
214+
/// <param name="relativeY"the relativeY coordinate of the desired cell></param>
168215
/// <returns>true if the cell is valid and false otherwise</returns>
169216
template <typename T>
170217
bool Grid<T>::validCoords(int x, int y)
@@ -175,8 +222,8 @@ bool Grid<T>::validCoords(int x, int y)
175222
/// <summary>
176223
/// Set the value of the cell at the given coordinates
177224
/// </summary>
178-
/// <param name="x">the x coordinate of the cell</param>
179-
/// <param name="y">the y coordinate of the cell</param>
225+
/// <param name="relativeX">the relativeX coordinate of the cell</param>
226+
/// <param name="relativeY">the relativeY coordinate of the cell</param>
180227
/// <param name="val">the new value of the given cell</param>
181228
/// <returns>true if the cell is valid and false otherwise</returns>
182229
template <typename T>

PathFinder.hpp

+89-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include "SFML/Graphics.hpp"
66
#include "Grid.hpp"
77
#include "GridCellStates.hpp"
8+
#include <vector>
9+
#include <unordered_set>
810

911
using namespace std;
1012
using namespace sf;
@@ -18,7 +20,16 @@ class PathFinder
1820
// node for each grid position
1921
struct GridNode
2022
{
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+
}
2233
};
2334

2435
private:
@@ -29,6 +40,17 @@ class PathFinder
2940
Vector2i* startPos;
3041
Vector2i* endPos;
3142

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+
3254
public:
3355
PathFinder(int width, int height, int cellSize);
3456

@@ -44,6 +66,8 @@ class PathFinder
4466

4567
bool setValAt(Vector2i pos, GridValue val);
4668

69+
GridNode* getShortestPath();
70+
4771
private:
4872
void initializeNodes();
4973

@@ -58,7 +82,9 @@ void PathFinder::initializeNodes()
5882
{
5983
for (int y = 0; y < grid->getGridHeight(); y++)
6084
{
61-
grid->setValAt(x, y, new GridNode());
85+
GridNode* newNode = new GridNode();
86+
newNode->gridPos = Vector2i(x, y);
87+
grid->setValAt(x, y, newNode);
6288
}
6389
}
6490
}
@@ -246,6 +272,67 @@ bool PathFinder::setValAt(Vector2i pos, GridValue val)
246272
return setValAt(gridPos.x, gridPos.y, val);
247273
}
248274

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+
}
249336

250337

251338
#endif // !PATH_FINDER_H

0 commit comments

Comments
 (0)