Hello there. Im working on an implementation of A* algorithm for my SFML game-project. I've recently got some problems with passing 2d arrays to a function (I think).
I got segmentation fault error when receving array[][sizex] (I have an idea why) and many other errors with array[sizey][sizex].
Lets take a look on the code:
aStar.hpp:
//(...)
class Node
{
public:
Node();
sf::Vector2i position;
sf::Vector2i parentPosition;
int gCost;
int hCost;
int fCost;
bool operator == (const Node & nod);
};
class aStar
{
public:
aStar();
int manhattan(sf::Vector2i start, sf::Vector2i end);
Node StartNode;
Node EndNode;
vector<Node> OpenSet;
vector<Node> ClosedSet;
vector<Node> NeighborSet;
vector<Node> PathSet;
void findPath(sf::Vector2i start, sf::Vector2i end, int tmap[10][10], int collisionMap[10][10]);
void buildPath();
int minfCost(vector<Node> vec);
void findNeighbors(Node CurrentNode, int tmap[10][10], int collisionMap[10][10]);
};
//(...)
aStar.cpp:
//(...)
aStar::aStar()
{
StartNode.parentPosition = sf::Vector2i(0,0);
}
Node::Node()
{
gCost = 0;
hCost = 0;
}
//int Node::fCost() { return gCost+hCost; }
void aStar::findNeighbors(Node CurrentNode, int tmap[10][10], int collisionMap[10][10])
{
for (int y=-1; y<=1; y++)
{
for (int x=-1; x<=1; x++)
{
int checkX=CurrentNode.position.x+x, checkY=CurrentNode.position.y+y;
if(x==0 && y==0) {continue; }
if(checkX < 0 || checkX > 10 || checkY < 0 || checkY > 10) {continue; }
if(collisionMap[checkY][checkX] == 0)
{
Node newNode;
newNode.position = sf::Vector2i(checkX, checkY);
newNode.parentPosition = CurrentNode.position;
if((newNode.position.x==CurrentNode.position.x && newNode.position.y!=CurrentNode.position.y) ||
(newNode.position.y==CurrentNode.position.y && newNode.position.x!=CurrentNode.position.x))
{
newNode.gCost = 10 + CurrentNode.gCost;
}
else
{
newNode.gCost = 14 + CurrentNode.gCost;
}
// OpenSet.push_back(newNode);
NeighborSet.push_back(newNode);
tmap[checkY][checkX] = 1;
}
}
}
}
bool Node::operator == (const Node & nod)
{ return (this->position == nod.position); }
int aStar::manhattan(sf::Vector2i start, sf::Vector2i end)
{
int dist;
dist = abs(start.x - end.x) + abs(start.y - end.y);
return (dist*10);
}
int aStar::minfCost(vector<Node> vec)
{ int min = vec[0].fCost;
unsigned int i=0;
for(; i<vec.size(); i++)
{
if(vec[i].fCost < min) {min =vec[i].fCost; }
}
return i;
}
void aStar::findPath(sf::Vector2i start, sf::Vector2i end, int tmap[10][10], int collisionMap[10][10])
{
StartNode.position = start;
StartNode.gCost = 0;
StartNode.fCost = StartNode.gCost + manhattan(start, end);
EndNode.position = end;
Node CurrentNode;
OpenSet.push_back(StartNode);
while (OpenSet.size() > 0)
{
CurrentNode = OpenSet[minfCost(OpenSet)];
if(CurrentNode == EndNode) { buildPath(); return ; }
OpenSet.erase( remove(OpenSet.begin(), OpenSet.end(), CurrentNode), OpenSet.end() );
ClosedSet.push_back(CurrentNode);
findNeighbors(CurrentNode, tmap, collisionMap);
for ( unsigned int i=0; i<NeighborSet.size(); i++)
{
if(find(ClosedSet.begin(), ClosedSet.end(), NeighborSet[i]) != ClosedSet.end() )
{
continue;
}
int tent = CurrentNode.gCost + manhattan(CurrentNode.position, NeighborSet[i].position);
if(! (find(OpenSet.begin(), OpenSet.end(), NeighborSet[i]) != OpenSet.end() ))
{// not found
OpenSet.push_back(NeighborSet[i]);
}
else if (tent >= NeighborSet[i].gCost)
{
continue;
}
NeighborSet[i].fCost = NeighborSet[i].gCost = manhattan(NeighborSet[i].position, EndNode.position);
}
}
}
void aStar::buildPath()
{
PathSet.push_back(EndNode);
Node newNode = EndNode;
while (newNode.parentPosition != sf::Vector2i(-1,-1)) // only possible if newNode == StartNode
{
newNode.position = newNode.parentPosition;
PathSet.push_back(newNode);
}
}
//(...)
I know it's a big piece of code, sorry for that, however I am not able to specify what's going wrong here.
I know this code Isn't the highest quality, I want to optimise it after I'll have it working
I use std namespace by default.
I got an error wherever I use
tmap[10][10] (ctrl+f it)
tmap is a 10x10 int array filled with 0,1,2,3 ("block" numbers)
collisionMap is a 10x10 int array filled with 0 if a "block" is walkable, 1 if isn't and 2 if a "block" is start/end of desired path.
If you think the only option is to rewrite the entire thing, just tell me. I'm looking for at least some tips if fixing this is not possible/worth.
Debugger output:
http://pastebin.com/uRFxyrXaI've been using those pseudocodes/tutorials: (+stack ofc)
http://www.growingwiththeweb.com/2012/06/a-pathfinding-algorithm.htmlhttps://en.wikipedia.org/wiki/A*_search_algorithmhttp://www.policyalmanac.org/games/aStarTutorial.htm