summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-10-07 02:46:16 +0200
committerStanislaw Halik <sthalik@misaki.pl>2023-10-07 02:46:16 +0200
commitbd3855592133bff90feef4fbecfd4fb84c861368 (patch)
tree7c631fccc049bedd4be271339f04693363b9132f
parent70d32f586ad17872809ca13f24d9fb36fb9ad213 (diff)
a
-rw-r--r--src/path-search-astar.cpp17
-rw-r--r--src/path-search-astar.hpp6
-rw-r--r--src/path-search-dijkstra.cpp38
3 files changed, 41 insertions, 20 deletions
diff --git a/src/path-search-astar.cpp b/src/path-search-astar.cpp
index ba73d23c..03225a33 100644
--- a/src/path-search-astar.cpp
+++ b/src/path-search-astar.cpp
@@ -1,5 +1,6 @@
#include "path-search-astar.hpp"
#include "compat/int-hash.hpp"
+#include <utility>
namespace floormat {
@@ -33,6 +34,20 @@ size_t astar_edge::hash() const
return fnvhash_32(this, sizeof *this);
}
+astar_edge astar_edge::swapped() const
+{
+ auto e = *this;
+ std::exchange(e.from_cx, e.to_cx);
+ std::exchange(e.from_cy, e.to_cy);
+ std::exchange(e.from_cz, e.to_cz);
+ std::exchange(e.from_t, e.to_t);
+ std::exchange(e.from_offx, e.to_offx);
+ std::exchange(e.from_offy, e.to_offy);
+ return e;
+}
+
+astar_edge::astar_edge() {}
+
bool operator<(const astar_edge_tuple& a, const astar_edge_tuple& b)
{
return b.dist < a.dist;
@@ -46,7 +61,7 @@ void astar::reserve(size_t count)
bool astar::add_visited(const astar_edge& value)
{
- return seen.insert(value).second;
+ return seen.insert(value).second && seen.insert(value.swapped()).second;
}
void astar::push(const astar_edge& value, uint32_t dist)
diff --git a/src/path-search-astar.hpp b/src/path-search-astar.hpp
index 494f96c7..f4b5774b 100644
--- a/src/path-search-astar.hpp
+++ b/src/path-search-astar.hpp
@@ -1,4 +1,5 @@
#pragma once
+#include "compat/defs.hpp"
#include "global-coords.hpp"
#include <vector>
@@ -17,10 +18,12 @@ struct astar_edge
friend struct astar_equal;
bool operator==(const astar_edge&) const noexcept;
+ fm_DECLARE_DEFAULT_COPY_ASSIGNMENT_(astar_edge);
astar_edge(global_coords coord1, Vector2b off1, global_coords coord2, Vector2b off2);
astar_edge(chunk_coords_ ch1, local_coords t1, Vector2b off1,
chunk_coords_ ch2, local_coords t2, Vector2b off2);
size_t hash() const;
+ astar_edge swapped() const;
int16_t from_cx, from_cy, to_cx, to_cy;
int8_t from_cz, to_cz;
@@ -28,6 +31,9 @@ struct astar_edge
int8_t from_offx, from_offy, to_offx, to_offy;
static constexpr auto INF = (uint32_t)-1;
+
+private:
+ astar_edge();
};
struct astar_edge_tuple
diff --git a/src/path-search-dijkstra.cpp b/src/path-search-dijkstra.cpp
index 404eb852..87b72a49 100644
--- a/src/path-search-dijkstra.cpp
+++ b/src/path-search-dijkstra.cpp
@@ -82,28 +82,28 @@ path_search_result path_search::Dijkstra(world& w, Vector2ub own_size, object_id
if (from_offset_len >= eps && is_passable(w, ch0, bb0, own_id, p))
astar.push({from, from_offset, from, from_offset}, from_offset_len);
- constexpr auto dirs = [] constexpr -> std::array<Vector2i, 8> {
- constexpr auto sqrt_2 = math::sqrt(2.f);
- std::array<Vector2i, 8> array = {{
- { -1, -1 },
- { 1, 1 },
- { -1, 1 },
- { 1, -1 },
- { -1, 0 },
- { 0, -1 },
- { 1, 0 },
- { 0, 1 },
+ struct pair { Vector2i dir; uint32_t len; };
+
+ constexpr auto dirs = [] constexpr -> std::array<pair, 8> {
+ constexpr auto len1 = path_search::div_size;
+ constexpr auto len2 = (uint32_t)(math::sqrt((float)len1.dot()) + 0.5f); // NOLINT
+ std::array<pair, 8> array = {{
+ { { -1, -1 }, len2 },
+ { { 1, 1 }, len2 },
+ { { -1, 1 }, len2 },
+ { { 1, -1 }, len2 },
+ { { -1, 0 }, len1.x() },
+ { { 0, -1 }, len1.y() },
+ { { 1, 0 }, len1.x() },
+ { { 0, 1 }, len1.y() },
}};
+ for (auto& [vec, len] : array)
+ vec *= path_search::div_size;
+#if 0
for (auto i = 0uz; i < array.size(); i++)
for (auto j = 0uz; j < i; j++)
- fm_assert(array[i] != array[j]);
- for (auto& vec : array)
- {
- if (vec.product() != 0)
- vec = Vector2i(Vector2(vec) * path_search::div_size * sqrt_2);
- else
- vec *= path_search::div_size;
- }
+ fm_assert(array[i].dir != array[j].dir);
+#endif
return array;
}();