Using std::set to sort nodes.
This commit is contained in:
@@ -61,7 +61,7 @@ func find_path() -> void:
|
|||||||
|
|
||||||
var arr = astar.find_path(from, to, check_box.button_pressed) # vrne Variant: null ali Array
|
var arr = astar.find_path(from, to, check_box.button_pressed) # vrne Variant: null ali Array
|
||||||
#print(arr)
|
#print(arr)
|
||||||
print(arr.size())
|
#print(arr.size())
|
||||||
|
|
||||||
if arr.size() > 1: # if the start and the end are the same there is no line to draw
|
if arr.size() > 1: # if the start and the end are the same there is no line to draw
|
||||||
# add new path
|
# add new path
|
||||||
|
|||||||
@@ -4,9 +4,7 @@
|
|||||||
#include <godot_cpp/core/error_macros.hpp>
|
#include <godot_cpp/core/error_macros.hpp>
|
||||||
#include <godot_cpp/variant/utility_functions.hpp>
|
#include <godot_cpp/variant/utility_functions.hpp>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <set>
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#define TERRAIN(x, y) (_terrain[(x) + (y) * _width])
|
#define TERRAIN(x, y) (_terrain[(x) + (y) * _width])
|
||||||
#define UNITS(x, y) (_units[(x) + (y) * _width])
|
#define UNITS(x, y) (_units[(x) + (y) * _width])
|
||||||
@@ -91,6 +89,33 @@ int Node::total_cost() const
|
|||||||
return distanceFromStart + distanceToEnd;
|
return distanceFromStart + distanceToEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Node::compare_nodes(const Node *left, const Node *right) {
|
||||||
|
if (left->total_cost() < right->total_cost())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (left->total_cost() > right->total_cost())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else // if (left->total_cost() == right->total_cost())
|
||||||
|
{
|
||||||
|
if (left->distanceToEnd < right->distanceToEnd)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (left->distanceToEnd > right->distanceToEnd)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else // if (left->distanceToEnd == right->distanceToEnd)
|
||||||
|
{
|
||||||
|
// make sure no two nodes are the same
|
||||||
|
return left < right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MultilevelAStarEx::_bind_methods()
|
void MultilevelAStarEx::_bind_methods()
|
||||||
{
|
{
|
||||||
ClassDB::bind_method(D_METHOD("init", "region"), &MultilevelAStarEx::init);
|
ClassDB::bind_method(D_METHOD("init", "region"), &MultilevelAStarEx::init);
|
||||||
@@ -114,10 +139,7 @@ MultilevelAStarEx::MultilevelAStarEx()
|
|||||||
_pass = 0;
|
_pass = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MultilevelAStarEx::~MultilevelAStarEx()
|
MultilevelAStarEx::~MultilevelAStarEx() { }
|
||||||
{
|
|
||||||
//UtilityFunctions::print("Destructor.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultilevelAStarEx::init(const Rect2i ®ion)
|
void MultilevelAStarEx::init(const Rect2i ®ion)
|
||||||
{
|
{
|
||||||
@@ -251,30 +273,34 @@ TypedArray<Vector2i> MultilevelAStarEx::find_path(const Vector2i &from, const Ve
|
|||||||
Vector2i from2 = from - _trans;
|
Vector2i from2 = from - _trans;
|
||||||
Vector2i to2 = to - _trans;
|
Vector2i to2 = to - _trans;
|
||||||
|
|
||||||
std::vector<Node *> open;
|
std::set<Node *, decltype(Node::compare_nodes)*> open(&Node::compare_nodes);
|
||||||
|
|
||||||
open.reserve(_width * _height);
|
|
||||||
|
|
||||||
Node *closest = &NODES(from2.x, from2.y);
|
Node *closest = &NODES(from2.x, from2.y);
|
||||||
closest->open(_pass, nullptr, 0, to2);
|
closest->open(_pass, nullptr, 0, to2);
|
||||||
open.push_back(closest);
|
open.insert(closest);
|
||||||
|
|
||||||
auto process = [this, &open, &to2, &closest](Node *current, int x, int y, int distance) {
|
auto process = [this, &open, &to2, &closest](Node *current, int x, int y, int distance) {
|
||||||
Node *node = &NODES(x, y);
|
Node *node = &NODES(x, y);
|
||||||
|
|
||||||
if (node->state(_pass) == Node::UNUSED)
|
if (node->state(_pass) == Node::CLOSED)
|
||||||
{
|
|
||||||
node->open(_pass, current, current->distanceFromStart + distance, to2);
|
|
||||||
open.push_back(node);
|
|
||||||
}
|
|
||||||
else if (node->state(_pass) == Node::CLOSED)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (node->state(_pass) == Node::UNUSED)
|
||||||
|
{
|
||||||
|
node->open(_pass, current, current->distanceFromStart + distance, to2);
|
||||||
|
open.insert(node);
|
||||||
|
}
|
||||||
else if (current->distanceFromStart + distance < node->distanceFromStart)
|
else if (current->distanceFromStart + distance < node->distanceFromStart)
|
||||||
{
|
{
|
||||||
|
auto nodeIter = open.find(node);
|
||||||
|
DEV_ASSERT(nodeIter != open.end());
|
||||||
|
open.erase(nodeIter);
|
||||||
|
|
||||||
node->parent = current;
|
node->parent = current;
|
||||||
node->distanceFromStart = current->distanceFromStart + distance;
|
node->distanceFromStart = current->distanceFromStart + distance;
|
||||||
|
|
||||||
|
open.insert(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the closest cell
|
// find the closest cell
|
||||||
@@ -293,19 +319,7 @@ TypedArray<Vector2i> MultilevelAStarEx::find_path(const Vector2i &from, const Ve
|
|||||||
|
|
||||||
while (!open.empty())
|
while (!open.empty())
|
||||||
{
|
{
|
||||||
// find closest to destination
|
Node *current = *open.begin();
|
||||||
Node *current = open[0];
|
|
||||||
for (Node *n : open)
|
|
||||||
{
|
|
||||||
if (n->total_cost() < current->total_cost())
|
|
||||||
{
|
|
||||||
current = n;
|
|
||||||
}
|
|
||||||
else if ((n->total_cost() == current->total_cost()) && (n->distanceToEnd < current->distanceToEnd))
|
|
||||||
{
|
|
||||||
current = n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current->distanceToEnd == 0)
|
if (current->distanceToEnd == 0)
|
||||||
{
|
{
|
||||||
@@ -314,8 +328,8 @@ TypedArray<Vector2i> MultilevelAStarEx::find_path(const Vector2i &from, const Ve
|
|||||||
}
|
}
|
||||||
|
|
||||||
// close it
|
// close it
|
||||||
|
open.erase(open.begin());
|
||||||
current->close(_pass);
|
current->close(_pass);
|
||||||
open.erase(std::remove(open.begin(), open.end(), current), open.end());
|
|
||||||
|
|
||||||
// expand it
|
// expand it
|
||||||
if (current->x - 1 >= 0) // left
|
if (current->x - 1 >= 0) // left
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ private:
|
|||||||
|
|
||||||
int distanceToEndForClosest;
|
int distanceToEndForClosest;
|
||||||
|
|
||||||
|
static bool compare_nodes(const Node *left, const Node *right);
|
||||||
|
|
||||||
Node(int x, int y);
|
Node(int x, int y);
|
||||||
void open(int pass, Node *parent, int distanceFromStart, const Vector2i &end);
|
void open(int pass, Node *parent, int distanceFromStart, const Vector2i &end);
|
||||||
void close(int pass);
|
void close(int pass);
|
||||||
|
|||||||
Reference in New Issue
Block a user