Implementing a* pathfinding in c++

  a-star, c++

Trying to implement A* pathfinding for a small game.
Running into some strange bugs.

Code:

class PathNode
{
private:
    const PathNode* parent;
    GameObject position;

    int g;
    int h;
    int f;

public:
    PathNode(GameObject _position, int _g, int _h, const PathNode* _parent = nullptr) {

        parent = _parent;
        position = _position;

        g = _g;  // distance between the start node and the current node
        h = _h;  // distance between the current node and the end node
        f = g + h;  // Total cost of the node (g + h)
    }

    PathNode(const PathNode& other) {

        position = other.position;
        g = other.g;  // distance between the start node and the current node
        h = other.h;  // distance between the current node and the end node
        f = other.f;  // Total cost of the node (g + h)

        parent = other.parent;
    }

    bool operator==(const PathNode& other) const {

        return (this->position == other.position);
    }

    bool operator!=(const PathNode& other) const {

        return !operator==(other);
    }

// GETTERS:
    int getg() const;
    int geth() const;
    int getf() const;
    const PathNode* getParent() const;
    const GameObject getPosition() const;

// SETTERS:
    void setg(int newG);
    void seth(int newH);
    void setf(int newF);
    void setParent(const PathNode* newParent);
    void setPosition(GameObject newPos);
};

And The PathFinding code:

char Ghost::aStar(char board[BoardYSize][BoardXSize], GameObject end) {

    int startEndDistance = pow((getX() - end.getX()), 2) + pow((getY() - end.getY()), 2);

    PathNode startNode(getPosition(), 0, startEndDistance);  // in the ctor of PathNode, the default values of Parent == nullptr.

    PathNode endNode(end, startEndDistance, 0);  // in the ctor of PathNode, the default values of Parent == nullptr.

    // Initialize both Open and Closed Lists:
    vector<PathNode> openList;
    vector<PathNode> closedList;

    openList.reserve(500);
    closedList.reserve(500);

    // Add the StartNode:
    openList.push_back(startNode);

    // Loop until you find the end:
    while (openList.size() > 0) {

        // Get the current Node.
        PathNode currentNode(openList[0]);  // Default copy ctor.

        int index = 0;

        for (int i = 0; i < openList.size(); i++) {

            if (openList[i].getf() < currentNode.getf()) {

                index = i;
                currentNode = openList[i];
            }
        }

        // Pop Current off openList, and add to closedList:
        openList.erase(openList.begin() + index);
        closedList.push_back(currentNode);

        // If found the end, return:
        if (currentNode == endNode) {

            // return direction of the first move of the path:
            const PathNode* nextNode = &currentNode;
            const PathNode* firstMoveNode = nullptr;

            while (*nextNode != startNode) {

                firstMoveNode = nextNode;
                nextNode = nextNode->getParent();
            }

            GameObject newPos = firstMoveNode->getPosition();
            GameObject currentPos = startNode.getPosition();

            if (newPos.getX() - currentPos.getX() == 0 && newPos.getY() - currentPos.getY() == 1)

                return 'w';

            else if (newPos.getX() - currentPos.getX() == 0 && newPos.getY() - currentPos.getY() == -1)

                return 'x';

            else if (newPos.getX() - currentPos.getX() == 1 && newPos.getY() - currentPos.getY() == 0)

                return 'd';

            else if (newPos.getX() - currentPos.getX() == -1 && newPos.getY() - currentPos.getY() == 0)

                return 'a';

            else
                return 's';
        }

        // Generate Children:
        vector <PathNode> children;

        // temp is used to generate the children of the currentNode.
        GameObject temp[4];
        temp[0] = GameObject(0, 1);   // Position above currentNode
        temp[1] = GameObject(1, 0);   // Position right of currentNode
        temp[2] = GameObject(0, -1);  // Position left of currentNode
        temp[3] = GameObject(-1, 0);  // Position below currentNode

        for (int i = 0 ; i < 4; i++) {

            // Get Node Position:
            GameObject nodePosition(currentNode.getPosition() + temp[i]);

            // Make Sure within Range of board & Not a Wall (walkable terrain):
            if (!checkLegalMove(nodePosition, board))

                continue;
            
            PathNode newNode(nodePosition, 0, 0, &currentNode);
            children.push_back(newNode);
        }

        // Loop through Children:

        for (auto child : children) {

            bool addChild = true;

            // Child is on the closedList:
            for (auto closedChild : closedList) {

                if (child == closedChild) {

                    addChild = false;
                    continue;
                }
            }

            if (!addChild)  continue;

            // Create the G H and F values:
            child.setg(currentNode.getg() + 1);
            child.seth(pow((child.getPosition().getX() - endNode.getPosition().getX()), 2) + pow((child.getPosition().getY() - endNode.getPosition().getY()), 2));
            child.setf(child.getg() + child.geth());

            // Child is already in the openList:
            for (auto openNode : openList) {

                if (child == openNode && child.getg() > openNode.getg()) {

                    addChild = false;
                    continue;
                }
            }

            if (!addChild)  continue;

            openList.push_back(child);
        }
    }

    return 's';
}

My goal is to use A* to find a route and simply return the direction of the first position to travel to.

The Problem I run into:
The problem is that when the condition of currentNode == endNode is met (reached the goal).
Every PathNode’s parent is simply a pointing to itself (according to the debugger).
I don’t understand why it’s happening, I assume The current pointer gets destroyed at some point in time but i can’t figure out why it’s happening.

Source: Windows Questions C++

LEAVE A COMMENT