From 997079e87425290762c0631aab77abe6e69f591c Mon Sep 17 00:00:00 2001 From: nhatdongdang <144138246+nhatdongdang@users.noreply.github.com> Date: Mon, 12 Aug 2024 17:15:08 +1000 Subject: [PATCH 1/2] Add iterator to HeightMap and documentation --- include/mcpp/util.h | 88 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/include/mcpp/util.h b/include/mcpp/util.h index 0ab1b891..53c87a77 100644 --- a/include/mcpp/util.h +++ b/include/mcpp/util.h @@ -158,6 +158,94 @@ struct Chunk { * non-air blocks at each (x,z) */ struct HeightMap { + /** + * @brief An iterator for the HeightMap structure. + * + * This iterator allows for range-based for loops and standard iterator + * operations over the height data stored within a HeightMap. + */ + struct Iterator { + using value_type = int; + using pointer = int*; + using reference = int&; + + /** + * @brief Constructs an iterator at the given pointer position. + * + * @param ptr Pointer to the position in the height array. + */ + Iterator(pointer ptr) : m_ptr(ptr) {} + + /** + * @brief Dereference the iterator to access the value at the current + * position. + * + * @return Reference to the current element. + */ + reference operator*() const { return *m_ptr; } + + /** + * @brief Access the pointer to the current element. + * + * @return Pointer to the current element. + */ + pointer operator->() { return m_ptr; } + + /** + * @brief Pre-increment operator. Advances the iterator to the next + * position. + * + * @return Reference to the updated iterator. + */ + Iterator& operator++() { + m_ptr++; + return *this; + } + + /** + * @brief Post-increment operator. Advances the iterator to the next + * position. + * + * @param int Unused dummy parameter to differentiate from prefix + * increment. + * @return Iterator to the original position before incrementing. + */ + Iterator operator++(int) { + Iterator tmp = *this; + ++(*this); + return tmp; + } + + /** + * @brief Equality comparison operator. + * + * @param a First iterator to compare. + * @param b Second iterator to compare. + * @return true if both iterators point to the same position, false + * otherwise. + */ + friend bool operator==(const Iterator& a, const Iterator& b) { + return a.m_ptr == b.m_ptr; + }; + + /** + * @brief Inequality comparison operator. + * + * @param a First iterator to compare. + * @param b Second iterator to compare. + * @return true if iterators point to different positions, false + * otherwise. + */ + friend bool operator!=(const Iterator& a, const Iterator& b) { + return a.m_ptr != b.m_ptr; + }; + + private: + pointer m_ptr; + }; + + Iterator begin() { return Iterator(&raw_heights[0]); } + Iterator end() { return Iterator(&raw_heights[_x_len * _z_len]); } HeightMap(const Coordinate& loc1, const Coordinate& loc2, const std::vector& heights); From 3cc7087dbc14e7f3bf3157a1bea35cfe82d506ff Mon Sep 17 00:00:00 2001 From: nhatdongdang <144138246+nhatdongdang@users.noreply.github.com> Date: Mon, 12 Aug 2024 17:15:22 +1000 Subject: [PATCH 2/2] Add testcase for heightmap iterator --- test/minecraft_tests.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/minecraft_tests.cpp b/test/minecraft_tests.cpp index 011aee4d..322b66aa 100644 --- a/test/minecraft_tests.cpp +++ b/test/minecraft_tests.cpp @@ -281,6 +281,32 @@ TEST_CASE("HeightMap functionality") { CHECK_EQ(data.get_worldspace(Coordinate{-201, 0, -202}), 301); } + SUBCASE("Iterator") { + mc.setBlocks(Coordinate{-200, 300, -200}, Coordinate{-210, 319, -210}, + Blocks::AIR); + mc.setBlocks(Coordinate{-200, 300, -200}, Coordinate{-210, 300, -210}, + Blocks::STONE); + mc.setBlock(Coordinate{-200, 301, -200}, Blocks::STONE); + mc.setBlock(Coordinate{-210, 301, -210}, Blocks::STONE); + mc.setBlock(Coordinate{-201, 301, -202}, Blocks::STONE); + + HeightMap data = + mc.getHeights(Coordinate{-200, 0, -200}, Coordinate{-210, 0, -210}); + + std::vector expected_heights; + for (int i = 0; i < data.x_len(); i++) { + for (int j = 0; j < data.z_len(); j++) { + expected_heights.push_back(data.get(i, j)); + } + } + + std::vector heights; + for (int height : data) { + heights.push_back(height); + } + CHECK_EQ(heights, expected_heights); + } + // Clean up mc.setBlocks(Coordinate{200, 300, 200}, Coordinate{210, 301, 210}, Blocks::AIR);