diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..1dd4a7f6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,50 @@ +{ + "files.associations": { + "__bit_reference": "cpp", + "__config": "cpp", + "__debug": "cpp", + "__errc": "cpp", + "__locale": "cpp", + "__mutex_base": "cpp", + "__threading_support": "cpp", + "__verbose_abort": "cpp", + "array": "cpp", + "atomic": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "exception": "cpp", + "initializer_list": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "limits": "cpp", + "locale": "cpp", + "mutex": "cpp", + "new": "cpp", + "optional": "cpp", + "ostream": "cpp", + "queue": "cpp", + "stack": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "typeinfo": "cpp", + "variant": "cpp", + "vector": "cpp", + "print": "cpp", + "algorithm": "cpp" + } +} \ No newline at end of file diff --git a/Doxyfile b/Doxyfile index efd988f2..aa53d8ca 100644 --- a/Doxyfile +++ b/Doxyfile @@ -2,7 +2,7 @@ DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "mcpp" PROJECT_NUMBER = PROJECT_BRIEF = "C++ Minecraft Library" -PROJECT_LOGO = +PROJECT_LOGO = "https://github.com/rozukke/mcpp/blob/main/resources/mcpplogosmall.png" OUTPUT_DIRECTORY = ./doc/ CREATE_SUBDIRS = NO CREATE_SUBDIRS_LEVEL = 8 diff --git a/include/mcpp/util.h b/include/mcpp/util.h index 72c1fcf8..954527cc 100644 --- a/include/mcpp/util.h +++ b/include/mcpp/util.h @@ -132,6 +132,95 @@ 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); diff --git a/test/minecraft_tests.cpp b/test/minecraft_tests.cpp index 00adb36a..5a3936dc 100644 --- a/test/minecraft_tests.cpp +++ b/test/minecraft_tests.cpp @@ -265,6 +265,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);