diff --git a/include/chunk.h b/include/chunk.h index 5f6e483db1e9d40b7f435d7e0fa8d82fff32f7fe..13a78b8a6ad459e14e26801724e2ba86db99b3c6 100644 --- a/include/chunk.h +++ b/include/chunk.h @@ -4,6 +4,7 @@ #include <cstdint> #include <cstdlib> #include <string> +#include <cstdlib> #include <iostream> #include "logger.h" @@ -30,12 +31,14 @@ class Chunk std::string getRadiationString() const; std::string getAgeString() const; + int valVisual(); + private: Logger& _logger; - int _x; - int _y; - int _z; + const int _x; + const int _y; + const int _z; uint16_t wealth; uint16_t weirdness; @@ -50,6 +53,7 @@ class Chunk int8_t magic; void generate_random(); + }; #endif // CHUNK_H diff --git a/include/main.h b/include/main.h index df761418d694c68ffada308fcddd239d1a4ca59a..efab70116a5388e1c74ba9649b6a8dede035f864 100644 --- a/include/main.h +++ b/include/main.h @@ -4,9 +4,15 @@ #include <iostream> #include <cstdint> +enum GenerationMethod +{ + Random +}; + #include "save-manager.h" #include "game-state.h" -#include "world-map.h" +#include "world-hex-2d.h" +#include "world-map-3d.h" #include "chunk.h" #include "logger.h" diff --git a/include/world-hex-2d.h b/include/world-hex-2d.h new file mode 100644 index 0000000000000000000000000000000000000000..c14482d61c7ffb301b2d64071024bb011c72d297 --- /dev/null +++ b/include/world-hex-2d.h @@ -0,0 +1,59 @@ +#ifndef WORLD_HEX_2D +#define WORLD_HEX_2D + +#include <unordered_map> + +#include "chunk.h" +#include "logger.h" +#include "ANSI-colour-codes.h" + +#include <string> +#include <iostream> + + +class WorldHex2D +{ + public: + WorldHex2D(); + WorldHex2D( uint8_t radius ); + WorldHex2D( uint8_t width, uint8_t height, uint8_t depth); + ~WorldHex2D(); + void generateWorld(); + + Chunk* getChunk( int chunkS, int chunkQ, int chunkR ); + + Chunk* getMidChunk(); + int getMidS(); + int getMidQ(); + int getMidR(); + + void visualise(); + void visualiseBlocky(); + Chunk* showChunk( int s, int q, int r ); + private: + Logger& _logger; + std::unordered_map<int, std::unordered_map<int, std::unordered_map<int, Chunk*>>> chunks_; + std::string colouriseValue( uint8_t val, int isSolid = 0 ); + + uint8_t _width; // s + uint8_t _height; // q + uint8_t _depth; // r + int _minS; // s + int _minQ; // q + int _minR; // r + int _maxS; // s + int _maxQ; // q + int _maxR; // r + + std::string visualiseBlock( + Chunk* core, + Chunk* topLeft, + Chunk* topRight, + Chunk* right, + Chunk* bottomRight, + Chunk* bottomLeft, + Chunk* left + ); +}; + +#endif // WORLD_HEX_2D diff --git a/include/world-map.h b/include/world-map-3d.h similarity index 63% rename from include/world-map.h rename to include/world-map-3d.h index 3f27d9b18dd6dfb7d2bd662310f57c00d493f23e..48df58b9fe5f3af289769bdce21e4bc7472ba27a 100644 --- a/include/world-map.h +++ b/include/world-map-3d.h @@ -1,22 +1,17 @@ -#ifndef WORLD_MAP_H -#define WORLD_MAP_H +#ifndef WORLD_MAP_3D_H +#define WORLD_MAP_3D_H #include <unordered_map> #include "chunk.h" #include "logger.h" -enum GenerationMethod -{ - Random -}; - -class WorldMap +class WorldMap3D { public: - WorldMap(); - WorldMap( uint8_t width, uint8_t height, uint8_t depth); - ~WorldMap(); + WorldMap3D(); + WorldMap3D( uint8_t width, uint8_t height, uint8_t depth); + ~WorldMap3D(); void generateWorld(); Chunk* getChunk( int chunkX, int chunkY, int chunkZ ); @@ -29,4 +24,4 @@ class WorldMap uint8_t _depth; // z }; -#endif // WORLD_MAP_H +#endif // WORLD_MAP_3D_H diff --git a/src/chunk.cpp b/src/chunk.cpp index a8d1abb181c6266289bb556dcded4e788b8f553f..a6630968c7be03025cb0d087819f1e4e2c593d0f 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -46,7 +46,8 @@ std::string Chunk::getRadiationString() const { return std::to_string(this->radi std::string Chunk::getAgeString() const { return std::to_string(this->age); } std::string Chunk::getString( ChunkQuery format ) const -{return "rest";} + {return "rest";} + std::string Chunk::getString() const { std::string str = "Chunk Details:" @@ -62,4 +63,10 @@ std::string Chunk::getString() const return str; } +int Chunk::valVisual() +{ + int val = this->density * 10 / ( 0xFFFF ); + return val == 0 ? 1 : val; +} + std::ostream& operator<<( std::ostream& os, const Chunk& obj ) { return os << obj.getString(); } diff --git a/src/main.cpp b/src/main.cpp index 098d38178ba09344540860e3ab1039851d4abdfa..953c27a8af6fd4a467eff7747f31f56d008ca352 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,11 +14,14 @@ int main() { srand(static_cast<unsigned int>(time(nullptr))); // Genrate a Random chunk - WorldMap map(2, 2, 2); + WorldHex2D map( 5 ); //Chunk* chunk = new Chunk( 0, 0, 0); //std::cout << chunk.getString() << std::endl; - Chunk* chunk = map.getChunk(0, 1, 0); - std::cout << chunk->getString() << std::endl; + // Chunk* chunk = map.getMidChunk(); + // std::cout << chunk->getString() << std::endl; + map.showChunk( 0, 0, 0 ); + map.showChunk( -2, 1, 1 ); + map.visualise(); // Menu Loop diff --git a/src/world-hex-2d.cpp b/src/world-hex-2d.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb279e5daca4ca423ba9c12e2bffff95b28c32ed --- /dev/null +++ b/src/world-hex-2d.cpp @@ -0,0 +1,207 @@ +#include "world-hex-2d.h" +WorldHex2D::WorldHex2D() : WorldHex2D( 5 ) {} +WorldHex2D::WorldHex2D( uint8_t radius ) + : WorldHex2D( + radius % 2 == 0 ? radius + 1 : radius, + radius % 2 == 0 ? radius + 1 : radius, + radius % 2 == 0 ? radius + 1 : radius +) {} + +WorldHex2D::WorldHex2D( uint8_t width, uint8_t height, uint8_t depth) + : _width( width ), _height( height ), _depth( depth ), + _logger( Logger::instance() ) +{ + this->_logger.info( "Creating Hex Map" ); + this->generateWorld(); +} +WorldHex2D::~WorldHex2D() +{ + this->_logger.info( "Cleaning world" ); + + // Clean Chunk Map + for( const auto& [keyX, value1] : this->chunks_) + { + for( const auto& [keyY, value2] : value1) + { + for( const auto& [keyZ, chunk] : value2) + { delete chunk; } + } + } +} +void WorldHex2D::generateWorld() +{ + this->_logger.info( "Generating initial world" ); + + this->_minS = this->_width / -2; // s + this->_minQ = this->_height / -2; // q + this->_minR = this->_depth / -2; // r + this->_maxS = ( this->_width / 2 ) + ( this->_width % 2 == 0 ? 0 : 1 ); + this->_maxQ = ( this->_height / 2 ) + ( this->_height % 2 == 0 ? 0 : 1 ); + this->_maxR = ( this->_depth / 2 ) + ( this->_depth % 2 == 0 ? 0 : 1 ); + + for( int s = this->_minS; s < this->_maxS; s++ ) + { + for( int q = this->_minQ; q < this->_maxQ; q++ ) + { + for( int r = this->_minR; r < this->_maxR; r++ ) + { + if( s + q + r == 0 ) + { + Chunk* chunk = new Chunk( s, q, r ); + this->chunks_[s][q][r] = chunk; + } + } + } + } +} + +Chunk* WorldHex2D::showChunk( int s, int q, int r ) +{ + Chunk* chunk = this->getChunk( s, q, r ); + if( !chunk ) + { + std::cout + << " Chunk Missing: [ " + << s << ", " + << q << ", " + << r << "] " + << std::endl; + return nullptr; + } + + // Get Neighbours + Chunk * tr = this->getChunk( s+1, q, r-1 ); + Chunk * xr = this->getChunk( s, q+1, r-1 ); + Chunk * br = this->getChunk( s-1, q+1, r ); + Chunk * bl = this->getChunk( s-1, q, r+1 ); + Chunk * xl = this->getChunk( s, q-1, r+1 ); + Chunk * tl = this->getChunk( s+1, q-1, r ); + + // Visualise + std::cout << chunk->getString() << std::endl; + + std::cout << this->visualiseBlock( chunk, tl, tr, xr, br, bl, xl ); + + return chunk; +} +std::string WorldHex2D::visualiseBlock( + Chunk* core, + Chunk* topLeft, + Chunk* topRight, + Chunk* right, + Chunk* bottomRight, + Chunk* bottomLeft, + Chunk* left +) { + int coreVal = core ? core->valVisual() : 0; + int tlVal = topLeft ? topLeft->valVisual() : 0; + int trVal = topRight ? topRight->valVisual() : 0; + int xrVal = right ? right->valVisual() : 0; + int brVal = bottomRight ? bottomRight->valVisual() : 0; + int blVal = bottomLeft ? bottomLeft->valVisual() : 0; + int xlVal = left ? left->valVisual() : 0; + std::cout << + " " << this->colouriseValue(tlVal) << " " << this->colouriseValue(trVal) << std::endl + << this->colouriseValue(xlVal) << " " << this->colouriseValue(coreVal, 1) << " " << this->colouriseValue(xrVal) << std::endl + <<" " << this->colouriseValue(blVal) << " " << this->colouriseValue(brVal) << std::endl; + return ""; +} + +Chunk* WorldHex2D::getChunk( int chunkS, int chunkQ, int chunkR ) +{ + auto chS = chunks_.find( chunkS ); + if( chS != chunks_.end() ) + { + auto chQ = chS->second.find( chunkQ ); + if( chQ != chS->second.end() ) + { + auto chR = chQ->second.find( chunkR ); + if( chR != chQ->second.end() ) + { return chR->second; } + } + } + + return nullptr; +} + +int WorldHex2D::getMidS(){ return this->_width / 2; } +int WorldHex2D::getMidQ(){ return this->_height / 2; } +int WorldHex2D::getMidR(){ return this->_depth / 2; } +Chunk* WorldHex2D::getMidChunk(){ + return this->getChunk( + getMidS(), + getMidQ(), + getMidR() + ); +} + +void WorldHex2D::visualise() +{ + this->_minS = this->_width / -2; // s + this->_minQ = this->_height / -2; // q + this->_minR = this->_depth / -2; // r + this->_maxS = ( this->_width / 2 ) + ( this->_width % 2 == 0 ? 0 : 1 ); + this->_maxQ = ( this->_height / 2 ) + ( this->_height % 2 == 0 ? 0 : 1 ); + this->_maxR = ( this->_depth / 2 ) + ( this->_depth % 2 == 0 ? 0 : 1 ); + + for( int s = this->_maxS; s >= this->_minS; s-- ) + { + for( int i = abs(s); i > 0; i-- ) + { std::cout << "\u2006"; } + // if( s % 2 != 0 ) { std::cout << "\u2006"; } + for( int q = this->_minQ; q < this->_maxQ; q++ ) + { + for( int r = this->_minR; r < this->_maxR; r++ ) + { + if( s + q + r == 0 ) + { + Chunk * chunk = this->getChunk( s,q,r ); + if( chunk ) + { + std::cout << " " << colouriseValue( chunk->valVisual() ); +// std::cout<<" \u2b21"; + } else { + std::cout <<" "; + } + // std::cout<<BLK<<" \u2b21"; + } + } + } + std::cout<<std::endl; + } + return; +} + +std::string WorldHex2D::colouriseValue( uint8_t val, int isSolid ) +{ + std::string valColour = ""; + if( val == 0 ) valColour = BLK; + else if( val < 2 ) valColour = BLU; + else if( val < 4 ) valColour = CYN; + else if( val < 6 ) valColour = YEL; + else if( val < 8 ) valColour = RED; + else valColour = MAG; + valColour = valColour + + (isSolid > 0 ? "\u2b22" : "\u2b21") + + CRESET; + return valColour; +} + +void WorldHex2D::visualiseBlocky() +{ + for( uint8_t s = 0; s < this->_width; s++ ) + { + for( uint8_t q = 0; q < this->_height; q++ ) + { + for( uint8_t r = 0; r < this->_depth; r++ ) + { + Chunk* chunk = getChunk( s, q, r ); + if( chunk ) + { std::cout << colouriseValue( chunk->valVisual(), 1 ); } + } + std::cout << std::endl; + } + std::cout << "#######" << std::endl; + } + std::cout << "TODO" << std::endl; +} diff --git a/src/world-map.cpp b/src/world-map3d.cpp similarity index 82% rename from src/world-map.cpp rename to src/world-map3d.cpp index d62043c544d454591bfdedbaeba371e85d235822..c34b95ae6b9ae95bcac7c27dbb16e49c509bc9d9 100644 --- a/src/world-map.cpp +++ b/src/world-map3d.cpp @@ -1,9 +1,9 @@ -#include "world-map.h" +#include "world-map-3d.h" -WorldMap::WorldMap() - :WorldMap( 5, 5, 5 ) +WorldMap3D::WorldMap3D() + :WorldMap3D( 5, 5, 5 ) {} -WorldMap::WorldMap( +WorldMap3D::WorldMap3D( uint8_t width, uint8_t height, uint8_t depth @@ -14,7 +14,7 @@ WorldMap::WorldMap( this->generateWorld(); } -WorldMap::~WorldMap(){ +WorldMap3D::~WorldMap3D(){ this->_logger.info( "Cleaning world" ); // Clean Chunk Map @@ -28,7 +28,7 @@ WorldMap::~WorldMap(){ } } -Chunk* WorldMap::getChunk(int chunkX, int chunkY, int chunkZ) +Chunk* WorldMap3D::getChunk(int chunkX, int chunkY, int chunkZ) { auto chX = chunks_.find( chunkX ); if( chX != chunks_.end() ) @@ -45,7 +45,7 @@ Chunk* WorldMap::getChunk(int chunkX, int chunkY, int chunkZ) return nullptr; } -void WorldMap::generateWorld() +void WorldMap3D::generateWorld() { this->_logger.info( "Generating initial world" ); for( uint8_t x = 0; x < this->_width; x++ )