Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2D Coordinate Type #103

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions example/pyramid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ int main() {
int min_height = *std::min_element(heights.begin(), heights.end());

// Build rings, diminishing up to pyramid height
mcpp::Coordinate base_pt = heights.base_pt();
base_pt.y = min_height;
mcpp::Coordinate base_pt = {heights.base_pt(), min_height};
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how I feel about this constructor... ordering seems important for an ordered x,y,z coordinate

int side_len = pyramid_base_len;
for (int i = 0; i < PYRAMID_HEIGHT; i++) {
make_ring(base_pt + mcpp::Coordinate(i, i, i), side_len - (i * 2));
Expand Down
16 changes: 8 additions & 8 deletions include/mcpp/mcpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,30 +125,30 @@ class MinecraftConnection {
Chunk getBlocks(const Coordinate& loc1, const Coordinate& loc2);

/**
* @brief Returns the height of the specific provided x and z coordinate
* @brief Returns the height of the specific provided 2D coordinate
*
* ***IMPORTANT:***
* DO NOT USE FOR LARGE AREAS, IT WILL BE VERY SLOW
* USE getHeights() INSTEAD
*
* Gets the y-value of the highest non-air block at the specified (x, z)
* Gets the y-value of the highest non-air block at the specified 2D
* coordinate.
* @param x
* @param z
* @param loc 2D coordinate
* @return Returns the integer y-height at the requested coordinate.
*/
int getHeight(int x, int z);
int getHeight(Coordinate2D loc);

/**
* @brief Provides a scaled option of the getHeight call to allow for
* considerable performance gains.
*
* \par USE THIS instead of getHeight in a for loop.
*
* @param loc1
* @param loc2
* @param loc1 1st corner of rectangle
* @param loc2 2nd corner of rectangle
* @return Returns a vector of integers representing the 2D area of heights.
*/
const HeightMap getHeights(const Coordinate& loc1, const Coordinate& loc2);
const HeightMap getHeights(const Coordinate2D& loc1,
const Coordinate2D& loc2);
};
} // namespace mcpp
122 changes: 115 additions & 7 deletions include/mcpp/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
*
*/
namespace mcpp {

struct Coordinate2D;

/**
* Represented using integers since sub-unit coordinates are not of particular
* relevance. Allows for operations such as addition between coordinates.
Expand All @@ -34,6 +37,15 @@ struct Coordinate {
*/
Coordinate(double x, double y, double z);

/**
* @brief Constructs a Coordinate object from a Coordinate2D object and a
* y value.
*
* @param coord The Coordinate2D object.
* @param y The y value.
*/
constexpr Coordinate(const Coordinate2D& coord, int y);

/**
* @brief Adds two Coordinate objects.
*
Expand Down Expand Up @@ -89,6 +101,102 @@ struct Coordinate {
int z;
};

/**
* @brief Height-agnostic coordinate class.
*
* Represented using integers since sub-unit coordinates are not of particular
* relevance. Allows for operations such as addition between flat coordinates.
*/
struct Coordinate2D {
/**
* @brief Constructs a Coordinate2D object with integer values.
*
* @param x The x-coordinate.
* @param z The z-coordinate.
*/
constexpr Coordinate2D(int x, int z) : x(x), z(z) {}

/**
* @brief Constructs a Coordinate2D object with zero values.
*/
constexpr Coordinate2D() : x(0), z(0) {}

/**
* @brief Constructs a Coordinate2D object with double values.
*
* @param x The x-coordinate as a double.
* @param z The z-coordinate as a double.
*/
constexpr Coordinate2D(double x, double z)
: x(static_cast<int>(x)), z(static_cast<int>(z)) {}

/**
* @brief Constructs a Coordinate2D object from a Coordinate object.
*
* @param coord The Coordinate object.
*/
constexpr Coordinate2D(const Coordinate& coord) : x(coord.x), z(coord.z) {}

/**
* @brief Adds two Coordinate2D objects.
*
* @param obj The Coordinate2D object to add.
* @return A new Coordinate2D object representing the sum of the two
* coordinates.
*/
Coordinate2D operator+(const Coordinate2D& obj) const;

// TODO: Add Coordinate + Coordinate2D

/**
* @brief Checks if two Coordinate2D objects are equal.
*
* @param obj The Coordinate2D object to compare with.
* @return True if the flat coordinates are equal, false otherwise.
*/
bool operator==(const Coordinate2D& obj) const;

/**
* @brief Checks if two Coordinate2D objects are not equal.
*
* @param obj The Coordinate2D object to compare with.
* @return True if the flat coordinates are not equal, false otherwise.
*/
bool operator!=(const Coordinate2D& obj) const;

/**
* @brief Subtracts one Coordinate2D object from another.
*
* @param obj The Coordinate2D object to subtract.
* @return A new Coordinate2D object representing the difference between
* the two coordinates.
*/
Coordinate2D operator-(const Coordinate2D& obj) const;

/**
* @brief Creates a copy of the Coordinate2D object.
*
* @return A new Coordinate2D object that is a copy of the current object.
*/
[[nodiscard]] Coordinate2D clone() const;

/**
* @brief Outputs the Coordinate2D object to an ostream.
*
* @param out The output stream.
* @param coord The Coordinate2D object to output.
* @return The output stream with the Coordinate object's values.
*/
friend std::ostream& operator<<(std::ostream& out,
const Coordinate2D& coord);

int x;
int z;
};

constexpr Coordinate::Coordinate(const Coordinate2D& coord, int y)
: x(coord.x), y(y), z(coord.z) {}

/**
* Stores a 3D cuboid of BlockTypes while preserving their relative location to
* the base point they were gathered at and each other.
Expand Down Expand Up @@ -343,7 +451,7 @@ struct HeightMap {

Iterator begin() { return Iterator(&raw_heights[0]); }
Iterator end() { return Iterator(&raw_heights[_x_len * _z_len]); }
HeightMap(const Coordinate& loc1, const Coordinate& loc2,
HeightMap(const Coordinate2D& loc1, const Coordinate2D& loc2,
const std::vector<int>& heights);

~HeightMap();
Expand All @@ -361,10 +469,10 @@ struct HeightMap {

/**
* Get the height at a Minecraft coordinate if saved inside the height map
* @param loc: Coordinate in Minecraft world to access in the map
* @param loc: 2D coordinate in Minecraft world to access in the map
* @return: height at specified coordinate
*/
int get_worldspace(const Coordinate& loc) const;
int get_worldspace(const Coordinate2D& loc) const;

/**
* Fill a coordinate inplace with the highest y coordinate at the `loc`'s x
Expand All @@ -386,13 +494,13 @@ struct HeightMap {
int z_len() const;

/**
* Gets the minimum coordinate in the HeightMap.
* @return the minimum coordinate in the HeightMap.
* Gets the minimum 2D coordinate in the HeightMap.
* @return the minimum 2D coordinate in the HeightMap.
*/
Coordinate base_pt() const;
Coordinate2D base_pt() const;

private:
Coordinate _base_pt;
Coordinate2D _base_pt;
int _x_len;
int _z_len;
int* raw_heights;
Expand Down
9 changes: 5 additions & 4 deletions src/mcpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,14 @@ Chunk MinecraftConnection::getBlocks(const Coordinate& loc1,
return Chunk{loc1, loc2, result};
}

int MinecraftConnection::getHeight(int x, int z) {
std::string returnValue = conn->sendReceiveCommand("world.getHeight", x, z);
int MinecraftConnection::getHeight(Coordinate2D loc) {
std::string returnValue =
conn->sendReceiveCommand("world.getHeight", loc.x, loc.z);
return stoi(returnValue);
}

const HeightMap MinecraftConnection::getHeights(const Coordinate& loc1,
const Coordinate& loc2) {
const HeightMap MinecraftConnection::getHeights(const Coordinate2D& loc1,
const Coordinate2D& loc2) {
std::string returnValue = conn->sendReceiveCommand(
"world.getHeights", loc1.x, loc1.z, loc2.x, loc2.z);

Expand Down
42 changes: 39 additions & 3 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,42 @@ std::ostream& operator<<(std::ostream& out, const Coordinate& coord) {
return out;
}

Coordinate2D Coordinate2D::operator+(const Coordinate2D& obj) const {
Coordinate2D result;
result.x = this->x + obj.x;
result.z = this->z + obj.z;
return result;
}

bool Coordinate2D::operator==(const Coordinate2D& obj) const {
return (this->x == obj.x) && (this->z == obj.z);
}

bool Coordinate2D::operator!=(const Coordinate2D& obj) const {
return !(*this == obj);
}

Coordinate2D Coordinate2D::operator-(const Coordinate2D& obj) const {
Coordinate2D result;
result.x = this->x - obj.x;
result.z = this->z - obj.z;
return result;
}

Coordinate2D Coordinate2D::clone() const {
return Coordinate2D(this->x, this->z);
}

std::string to_string(const Coordinate2D& coord) {
using std::to_string;
return "(" + to_string(coord.x) + "," + to_string(coord.z) + ")";
}

std::ostream& operator<<(std::ostream& out, const Coordinate2D& coord) {
out << to_string(coord);
return out;
}

Chunk::Chunk(const Coordinate& loc1, const Coordinate& loc2,
const std::vector<BlockType>& block_list) {
Coordinate min{std::min(loc1.x, loc2.x), std::min(loc1.y, loc2.y),
Expand Down Expand Up @@ -120,7 +156,7 @@ int Chunk::z_len() const { return this->_z_len; }

Coordinate Chunk::base_pt() const { return this->_base_pt.clone(); }

HeightMap::HeightMap(const Coordinate& loc1, const Coordinate& loc2,
HeightMap::HeightMap(const Coordinate2D& loc1, const Coordinate2D& loc2,
const std::vector<int>& heights) {
_base_pt = Coordinate{
std::min(loc1.x, loc2.x),
Expand Down Expand Up @@ -167,7 +203,7 @@ int HeightMap::get(int x, int z) const {
return raw_heights[x * _z_len + z];
}

int HeightMap::get_worldspace(const Coordinate& loc) const {
int HeightMap::get_worldspace(const Coordinate2D& loc) const {
return get(loc.x - _base_pt.x, loc.z - _base_pt.z);
}

Expand All @@ -179,6 +215,6 @@ int HeightMap::x_len() const { return this->_x_len; }

int HeightMap::z_len() const { return this->_z_len; }

Coordinate HeightMap::base_pt() const { return this->_base_pt.clone(); }
Coordinate2D HeightMap::base_pt() const { return this->_base_pt.clone(); }

} // namespace mcpp
2 changes: 1 addition & 1 deletion test/minecraft_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ TEST_CASE("Test the main mcpp class") {
SUBCASE("getHeight") {
Coordinate heightTestLoc(300, 200, 300);
mc.setBlock(heightTestLoc, Blocks::DIRT);
auto height = mc.getHeight(heightTestLoc.x, heightTestLoc.z);
auto height = mc.getHeight(heightTestLoc);
CHECK_EQ(height, heightTestLoc.y);

// Clean up
Expand Down
Loading