Skip to content

Commit

Permalink
Merge pull request #65 from rozukke/add/chunk-getters
Browse files Browse the repository at this point in the history
Add getters and fix constructor and destructor problems
  • Loading branch information
rozukke authored Aug 12, 2024
2 parents 9acbc53 + 85f7e6c commit c05bed4
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 15 deletions.
40 changes: 35 additions & 5 deletions include/mcpp/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ struct Chunk {

~Chunk();

Chunk& operator=(const Chunk& other) noexcept;

/**
* Accesses the Minecraft block at absolute position pos and returns its
* BlockType if it is in the included area.
Expand All @@ -119,12 +121,36 @@ struct Chunk {
*/
BlockType get(int x, int y, int z);

/**
* Gets the x length of the Chunk.
* @return x length of the Chunk
*/
int x_len() const;

/**
* Gets the y length of the Chunk.
* @return y length of the Chunk
*/
int y_len() const;

/**
* Gets the z length of the Chunk.
* @return z length of the Chunk
*/
int z_len() const;

/**
* Gets the minimum coordinate in the Chunk.
* @return the minimum coordinate in the Chunk
*/
Coordinate base_pt() const;

private:
Coordinate base_pt;
Coordinate _base_pt;
int _y_len;
int _x_len;
int _z_len;
BlockType* raw_data;
int y_len;
int x_len;
int z_len;
};

/**
Expand All @@ -135,6 +161,10 @@ struct HeightMap {
HeightMap(const Coordinate& loc1, const Coordinate& loc2,
const std::vector<int>& heights);

~HeightMap();

HeightMap& operator=(const HeightMap& other) noexcept;

/**
* Get the height using an offset from the origin/base point of the heights
* area
Expand Down Expand Up @@ -177,9 +207,9 @@ struct HeightMap {
Coordinate base_pt() const;

private:
Coordinate _base_pt;
int _x_len;
int _z_len;
Coordinate _base_pt;
int* raw_heights;
};

Expand Down
66 changes: 56 additions & 10 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,40 +60,66 @@ 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),
std::min(loc1.z, loc2.z)};
this->base_pt = min.clone();
this->_base_pt = min.clone();

Coordinate dim = loc1 - loc2;
x_len = std::abs(dim.x) + 1;
y_len = std::abs(dim.y) + 1;
z_len = std::abs(dim.z) + 1;
_x_len = std::abs(dim.x) + 1;
_y_len = std::abs(dim.y) + 1;
_z_len = std::abs(dim.z) + 1;

this->raw_data = new BlockType[block_list.size()];
std::copy(block_list.begin(), block_list.end(), raw_data);
}

Chunk::~Chunk() { delete[] raw_data; }

Chunk& Chunk::operator=(const Chunk& other) noexcept {
if (this != &other) {
// Clean up existing resource
delete[] raw_data;

// Copy data from the other object
_base_pt = other._base_pt.clone();
_x_len = other._x_len;
_y_len = other._y_len;
_z_len = other._z_len;
raw_data = new BlockType[_x_len * _y_len * _z_len];
std::copy(other.raw_data, other.raw_data + _x_len * _y_len * _z_len,
raw_data);
}
return *this;
}

BlockType Chunk::get(int x, int y, int z) {
if ((x < 0 || y < 0 || z < 0) ||
(x > x_len - 1 || y > y_len - 1 || z > z_len - 1)) {
(x > _x_len - 1 || y > _y_len - 1 || z > _z_len - 1)) {
throw std::out_of_range("Out of bounds Chunk access at " +
to_string(Coordinate(x, y, z)));
}
return raw_data[z + z_len * (x + y_len * y)];
return raw_data[z + _z_len * (x + _y_len * y)];
}

BlockType Chunk::get_worldspace(const Coordinate& pos) {
Coordinate array_pos = pos - base_pt;
Coordinate array_pos = pos - _base_pt;
if ((array_pos.x < 0 || array_pos.y < 0 || array_pos.z < 0) ||
(array_pos.x > x_len - 1 || array_pos.y > y_len - 1 ||
array_pos.z > z_len - 1)) {
(array_pos.x > _x_len - 1 || array_pos.y > _y_len - 1 ||
array_pos.z > _z_len - 1)) {
throw std::out_of_range("Out of bounds Chunk access at " +
to_string(array_pos) + " (world coordinate " +
to_string(pos) + " )");
}
return raw_data[array_pos.z + z_len * (array_pos.x + y_len * array_pos.y)];
return raw_data[array_pos.z +
_z_len * (array_pos.x + _y_len * array_pos.y)];
}

int Chunk::x_len() const { return this->_x_len; }

int Chunk::y_len() const { return this->_y_len; }

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,
const std::vector<int>& heights) {
_base_pt = Coordinate{
Expand All @@ -109,6 +135,26 @@ HeightMap::HeightMap(const Coordinate& loc1, const Coordinate& loc2,
std::copy(heights.begin(), heights.end(), raw_heights);
}

HeightMap::~HeightMap() { delete[] raw_heights; }

HeightMap& HeightMap::operator=(const HeightMap& other) noexcept {
if (this != &other) {
// Free the existing resource
delete[] raw_heights;

// Copy data from the other object
_base_pt = other._base_pt.clone();
_x_len = other._x_len;
_z_len = other._z_len;

// Allocate memory and copy the heights
raw_heights = new int[_x_len * _z_len];
std::copy(other.raw_heights, other.raw_heights + _x_len * _z_len,
raw_heights);
}
return *this;
}

int HeightMap::get(int x, int z) const {
if ((x < 0 || x >= _x_len) || (z < 0 || z >= _z_len)) {
throw new std::out_of_range(
Expand Down
16 changes: 16 additions & 0 deletions test/minecraft_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,22 @@ TEST_CASE("getBlocks and Chunk operations") {
mc.setBlock(loc1 + Coordinate{1, 2, 3}, Blocks::IRON_BLOCK);
Chunk res = mc.getBlocks(loc1, loc2);

SUBCASE("getters") {
Chunk data = mc.getBlocks(loc1, loc2);

CHECK_EQ(data.base_pt(), loc1);
CHECK_EQ(data.x_len(), 11);
CHECK_EQ(data.y_len(), 11);
CHECK_EQ(data.z_len(), 11);

data = mc.getBlocks(loc2, loc1);

CHECK_EQ(data.base_pt(), loc1);
CHECK_EQ(data.x_len(), 11);
CHECK_EQ(data.y_len(), 11);
CHECK_EQ(data.z_len(), 11);
}

SUBCASE("Block accessing returns correct block using get()") {
CHECK_EQ(res.get(0, 0, 0), Blocks::GOLD_BLOCK);
CHECK_EQ(res.get(1, 1, 1), Blocks::BRICKS);
Expand Down

0 comments on commit c05bed4

Please sign in to comment.