Hello, I am attempting to create my own version of A*. The trouble I'm having is mainly that my program isn't finding the closed nodes properly. And all in all I'm not sure if I'm even doing it the right way. Is there anyone that can help point me in the right direction?
Here is my code:
PathFinder.cpp
PathFinder::PathFinder(unsigned int width, unsigned int height, std::vector<int> newMap)
{
this->width = width;
this->height = height;
for (unsigned int i = 0; i < width; ++i)
{
for (unsigned int j = 0; j < height; ++j)
{
// Create our map and assign the nodes their positions
map.push_back(new Node(i * 32, j * 32));
// If there is a collision node here, add it to the closed list
if(newMap[i + j] > 0)
{
closedList.push_back(map[i + j]);
}
}
}
}
PathFinder::~PathFinder()
{
}
bool PathFinder::checkClosed(Node *node)
{
for (std::vector<Node*>::iterator it = closedList.begin() ; it != closedList.end(); ++it)
{
if(*it == node)
{
return true;
}
}
return false;
}
bool PathFinder::checkOpen(Node *node)
{
for (std::vector<Node*>::iterator it = openList.begin() ; it != openList.end(); ++it)
{
if(*it == node)
{
//std::cout << "a" << std::endl;
return true;
}
}
return false;
}
std::vector<int> PathFinder::findPath(Node &start, Node &finish)
{
// Initalize variables
for(std::vector<Node*>::iterator it = map.begin() ; it != map.end(); ++it)
{
// Reset our list
(*it)->Gvalue = 10;
(*it)->Hvalue = 0;
(*it)->searchX = 0;
(*it)->searchY = 0;
(*it)->shape.setFillColor(sf::Color::Black);
}
foundFinish = false;
std::vector<int> result;
closedList.clear();
openList.clear();
// Set our parent node to the start of the search area
nodeParent = &start;
// Add our parent node to the open list
// to search for surrounding nodes
openList.push_back(nodeParent);
// For debugging
openList[0]->shape.setFillColor(sf::Color::Blue);
while(!foundFinish)
{
// Search for surrounding nodes not in the closed list
for(unsigned int i=0; i < openList.size(); i++)
{
// IF we've found the finish
if(openList[i]->x == finish.x && openList[i]->y == finish.y)
{
foundFinish = true;
}
// If we've found the finish
if(openList[i]->x == finish.x && openList[i]->y == finish.y)
{
// We've found the node, so finish here
foundFinish = true;
openList[i]->shape.setFillColor(sf::Color::Green);
// Exit out of the loop
break;
}
for(std::vector<Node*>::iterator it = map.begin() ; it != map.end(); ++it)
{
// Find node to the left of us
if(((*it)->x == openList[i]->x-32 && (*it)->y == openList[i]->y))
{
if(!checkClosed(*it) && !checkOpen(*it))
{
// Add to the GValue
(*it)->Gvalue += openList[i]->Gvalue;
// Set our Hvalue to the shortest path
(*it)->setShortestPath(finish);
// Calculate our Fvalue F = G + H
(*it)->calculateHValue();
openList.push_back(*it);
}
}
// Find node to the left-diagonal of us
if(((*it)->x == openList[i]->x-32 && (*it)->y == openList[i]->y-32))
{
if(!checkClosed(*it) && !checkOpen(*it))
{
// Add to the GValue
(*it)->Gvalue += openList[i]->Gvalue + 4;
// Set our Hvalue to the shortest path
(*it)->setShortestPath(finish);
// Calculate our Fvalue F = G + H
(*it)->calculateHValue();
openList.push_back(*it);
}
}
// Find node to the right of us
if((*it)->x == openList[i]->x+32 && (*it)->y == openList[i]->y)
{
if(!checkClosed(*it) && !checkOpen(*it))
{
// Add to the GValue
(*it)->Gvalue += openList[i]->Gvalue;
// Set our Hvalue to the shortest path
(*it)->setShortestPath(finish);
// Calculate our Fvalue F = G + H
(*it)->calculateHValue();
openList.push_back(*it);
}
}
// Find node to the right- diagonal of us
if((*it)->x == openList[i]->x+32 && (*it)->y == openList[i]->y-32)
{
if(!checkClosed(*it) && !checkOpen(*it))
{
// Add to the GValue
(*it)->Gvalue += openList[i]->Gvalue + 4;
// Set our Hvalue to the shortest path
(*it)->setShortestPath(finish);
// Calculate our Fvalue F = G + H
(*it)->calculateHValue();
openList.push_back(*it);
}
}
// Find node below us
if((*it)->x == openList[i]->x && (*it)->y == openList[i]->y + 32)
{
if(!checkClosed(*it) && !checkOpen(*it))
{
// Add to the GValue
(*it)->Gvalue += openList[i]->Gvalue;
// Set our Hvalue to the shortest path
(*it)->setShortestPath(finish);
// Calculate our Fvalue F = G + H
(*it)->calculateHValue();
openList.push_back(*it);
}
}
// Find node right-below diagonal us
if((*it)->x == openList[i]->x + 32 && (*it)->y == openList[i]->y + 32)
{
if(!checkClosed(*it) && !checkOpen(*it))
{
// Add to the GValue
(*it)->Gvalue += openList[i]->Gvalue + 4;
// Set our Hvalue to the shortest path
(*it)->setShortestPath(finish);
// Calculate our Fvalue F = G + H
(*it)->calculateHValue();
openList.push_back(*it);
}
}
// Find node above us
if((*it)->x == openList[i]->x && (*it)->y == openList[i]->y-32)
{
if(!checkClosed(*it) && !checkOpen(*it))
{
// Add to the GValue
(*it)->Gvalue += openList[i]->Gvalue;
// Set our Hvalue to the shortest path
(*it)->setShortestPath(finish);
// Calculate our Fvalue F = G + H
(*it)->calculateHValue();
openList.push_back(*it);
}
}
// Find node above-left diagonal us
if((*it)->x == openList[i]->x-32 && (*it)->y == openList[i]->y-32)
{
if(!checkClosed(*it) && !checkOpen(*it))
{
// Add to the GValue
(*it)->Gvalue += openList[i]->Gvalue + 4;
// Set our Hvalue to the shortest path
(*it)->setShortestPath(finish);
// Calculate our Fvalue F = G + H
(*it)->calculateHValue();
openList.push_back(*it);
}
}
}
// Remove the current node from the open list to the closed list
closedList.push_back(openList[i]);
//openList.erase(openList.begin());
std::sort(openList.begin(), openList.end(), sortByFValue);
i = 0;
}
std::cout << "Found path ";
// After for loop
}
return result;
}
Node.cpp
Node::Node(unsigned int xPos, unsigned int yPos)
{
x = xPos;
y = yPos;
}
bool Node::compareNode(Node other)
{
if(other.x == searchX && searchY == other.y)
{
return true;
}
else
{
return false;
}
}
void Node::calculateHValue()
{
Fvalue = Gvalue + Hvalue;
}
void Node::setShortestPath(Node other)
{
searchX = x;
searchY = y;
// While we aren't the finish node
while(!compareNode(other))
{
// std::cout << "x: " << searchX << " y: " << searchY << " finding: " << other.x << " " << other.y << std::endl;
// Move our search x and y to the node
if(searchX > other.x)
{
searchX -= 32;
}
else if(searchX < other.x)
{
searchX += 32;
}
else if(searchY > other.y)
{
searchY -= 32;
}
else if(searchY < other.y)
{
searchY += 32;
}
// Increment our Hvalue
Hvalue += 1;
}
}