#include "AStar.h"
#include "Node.h"
#include "EntityManager.h"
#include <algorithm>
#include <iostream>
#include <unordered_set>
#include <queue>
using namespace Dotmk_AI;
using namespace Dotmk_Managers;
AStar::AStar()
{
}
std::vector<Node*> AStar::GeneratePath(Node* start, Node* goal)
{
intstd::vector<std::vector<Node*>>* cpNodeMap = 0;EntityManager::GetAStar()->GetNodeMap();
std::vector<Node*> openSet;
std::vector<Node*>unordered_set<Node*> closedSet;
make_heap(openSet.begin(), openSet.end());
start->g = 0;
openSet.push_back(start);
push_heap(openSet.begin(), openSet.end());
while (openSet.size() > 0)
{
Node* currentNode = openSet.at(0);openSet[0];
for (int i = 0; i < openSet.size(); ++i)
{
if (openSet.at(i)openSet[0]->f < currentNode->f || openSet.at(i)openSet[0]->f == currentNode->f && openSet.at(i)openSet[0]->h < currentNode->h)
{
currentNode = openSet.at(i);openSet[i];
}
}
Remove(&openSet, currentNode);
closedSet.push_backinsert(currentNode);
if (currentNode->x == goal->x && currentNode->y == goal->y)
{
goal->parent = currentNode->parent;
break;
}
for (Node* neighbour : GetNeighbours(currentNode, pNodeMap))
{
if (neighbour != nullptr)
{
if (Contains(&closedSetclosedSet, neighbour) || neighbour->e == 0) continue;
int newMovementCostToNeighbour = currentNode->g + GetDistance(currentNode, neighbour) + neighbour->penalty;;
if (newMovementCostToNeighbour < neighbour->g || !Contains(&openSetopenSet, neighbour))
{
neighbour->g = newMovementCostToNeighbour;
neighbour->h = GetDistance(neighbour, goal);
neighbour->f = neighbour->g + neighbour->h;
neighbour->parent = currentNode;
if (!Contains(&closedSetopenSet, neighbour)) openSet.push_back(neighbour);
else openSet;
}
}
}
}
std::vector<Node*> nodes;
Node* current = goal;
while (current != nullptr)
{
nodes.push_back(current);
current = current->parent;
}
reverse(nodes.begin(), nodes.end());
nodes.pop_back();
std::cout << nodes.size() << std::endl;
return nodes;
}
int AStar::GetDistance(Node* nodeA, Node* nodeB)
{
int distX = abs(nodeA->x - nodeB->x);
int distY = abs(nodeA->y - nodeB->y);
if
(distX > distY) return distY1 * (distX - distY);
return* distX + (distY -* distXdistY);
}
std::vector<Node*> AStar::GetNeighbours(Node* _pNode, std::vector<std::vector<Node*>>* _pNodeMap)
{
std::vector<Node*> neighbours;
neighbours.reserve(8);
for (int x = -1; x <= 1; ++x)
{
if (_pNode == nullptr)
{
break;
}
for (int y = -1; y <= 1; ++y)
{
if (x == 0 && y == 0) continue;
int checkX = _pNode->x + x;
int checkY = _pNode->y + y;
if (checkX >= 0 && checkX < 51264 && checkY >= 0 && checkY < 51264)
{
neighbours.push_back(GetNodeAt(checkX, checkY*_pNodeMap)[checkX][checkY]);
}
}
}
return neighbours;
}
bool AStar::Contains(std::vector<Node*>*vector<Node*> _pVector, Node* _pNode)
{
if(_pNode == nullptr)
{
return false;
}
if (find(_pVector->begin.begin(), _pVector->end.end(), _pNode) != _pVector->end.end())
{
return true;;
}
return false;
}
voidbool AStar::RemoveContains(std::vector<Node*>*unordered_set<Node*> _pVector, Node* _pNode)
{
forreturn find(std::vector<Node*>::iterator iter = _pVector->begin.begin(); iter !=, _pVector->end.end(); ++iter)
{
if (*iter ==, _pNode)
{
!= _pVector->erase.end(iter);
break;
}
}
}
Node*void AStar::GetNodeAtRemove(intstd::vector<Node*>* _x_pVector, intNode* _y_pNode)
{
for (Node*int nodepos := EntityManager::GetInstancefind()_pVector->GetAStar>begin(), _pVector->GetNodeMap>end())
{
, if_pNode) (node->x == _x && node_pVector->y == _y>begin()
{;
auto it = _pVector->begin() return+ node;pos;
}
rotate(it, it + 1, }_pVector->end());
return nullptr;_pVector->pop_back();
}
EDIT: Setting it on Release mode will make the pathfinding ALMOST instant, but still noticable. I've taken much of your guys advice and improved the code.