From 4d02bfdeeaede1e8b258f735b3b49f03de982fdf Mon Sep 17 00:00:00 2001 From: Johnathan Date: Wed, 2 Apr 2025 11:14:40 +1100 Subject: [PATCH 1/2] feature/hashing --- include/mcpp/coordinate.h | 9 +++++++++ src/coordinate.cpp | 14 ++++++++++++++ test/local_tests.cpp | 17 +++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/include/mcpp/coordinate.h b/include/mcpp/coordinate.h index 6cbdf18..3bd4917 100644 --- a/include/mcpp/coordinate.h +++ b/include/mcpp/coordinate.h @@ -74,6 +74,15 @@ struct Coordinate { */ Coordinate operator-(const Coordinate& obj) const; + /** + * @brief Implements hash algorithm for Coordinate object using non-negative + * mapping and weighted coordinate values. + * + * @param obj The Coordinate object to hash. + * @return Hash of Coordinate object. + */ + std::size_t operator()(const Coordinate& obj) const; + /** * @brief Outputs the Coordinate object to an ostream. * diff --git a/src/coordinate.cpp b/src/coordinate.cpp index 09f47f1..01db302 100644 --- a/src/coordinate.cpp +++ b/src/coordinate.cpp @@ -24,6 +24,20 @@ Coordinate Coordinate::operator-(const Coordinate& obj) const { return result; } +std::size_t Coordinate::operator()(const mcpp::Coordinate& obj) const { + // Minecraft coordinate bounds + int lower = -3e7, upper = 3e7; + size_t base = upper - lower + 1; + + // Convert coordinate attributes to non-negative values + size_t nx = obj.x - lower; + size_t ny = obj.y - lower; + size_t nz = obj.z - lower; + + // Combine and weight coordinate values using the boundary range + return nx * base * base + ny * base + nz; +} + std::string to_string(const Coordinate& coord) { using std::to_string; return "(" + to_string(coord.x) + "," + to_string(coord.y) + "," + to_string(coord.z) + ")"; diff --git a/test/local_tests.cpp b/test/local_tests.cpp index d650ebb..88296ab 100644 --- a/test/local_tests.cpp +++ b/test/local_tests.cpp @@ -3,6 +3,7 @@ #include "../include/mcpp/block.h" #include "../include/mcpp/coordinate.h" #include "doctest.h" +#include // NOLINTBEGIN @@ -22,6 +23,22 @@ TEST_CASE("Test Coordinate class") { CHECK_EQ(test_coord.z, 0); } + SUBCASE("Test hash no collision") { + const int seed = 12345; + std::set hashes; + std::mt19937 gen(seed); + std::uniform_int_distribution dis(-3e7, 3e7); + std::uniform_int_distribution dis2(-64, 256); + + Coordinate hashing; + for (int i = 0; i < 100; i++) { + Coordinate testCoord(dis(gen), dis2(gen), dis(gen)); + size_t hash = hashing(testCoord); + hashes.insert(hash); + } + CHECK_EQ(hashes.size(), 100); + } + SUBCASE("Test double init") { Coordinate test_coord(1.5, 2.5, 3.5); Coordinate test_coord_float(1.5F, 2.5F, 3.5F); From 681cbe83760203045521350935a9c904bc5ca2ba Mon Sep 17 00:00:00 2001 From: Johnathan Date: Wed, 2 Apr 2025 11:48:14 +1100 Subject: [PATCH 2/2] fix: styling issues --- src/coordinate.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/coordinate.cpp b/src/coordinate.cpp index 01db302..37f6630 100644 --- a/src/coordinate.cpp +++ b/src/coordinate.cpp @@ -25,16 +25,13 @@ Coordinate Coordinate::operator-(const Coordinate& obj) const { } std::size_t Coordinate::operator()(const mcpp::Coordinate& obj) const { - // Minecraft coordinate bounds int lower = -3e7, upper = 3e7; size_t base = upper - lower + 1; - // Convert coordinate attributes to non-negative values size_t nx = obj.x - lower; size_t ny = obj.y - lower; size_t nz = obj.z - lower; - // Combine and weight coordinate values using the boundary range return nx * base * base + ny * base + nz; }