diff --git a/includes/Entities/rock.hpp b/includes/Entities/rock.hpp index 9118327..e49e123 100644 --- a/includes/Entities/rock.hpp +++ b/includes/Entities/rock.hpp @@ -14,6 +14,7 @@ class Rock: public Entity { std::optional getPrimaryPos(void) const override { return this->location; } void simulateExistence() override {} + void pauseExistence() override {} Rock(World_Ptr); Rock(World_Ptr, const coord&); diff --git a/includes/config.hpp b/includes/config.hpp index a21bcf5..a66cead 100644 --- a/includes/config.hpp +++ b/includes/config.hpp @@ -12,7 +12,7 @@ namespace statics static constexpr uint16_t init_Bound{ 40, }; //applicable to A NEW WORLD static constexpr float max_free_space = 1000.0f; //so that space doesn't just get wasted - static constexpr float min_free_space = 100.0f; //if it falls below this, in a particular worlPlot, the expansion rate will be increased + static constexpr float min_free_space = 10.0f; //if it falls below this, in a particular worlPlot, the expansion rate will be increased static constexpr _timePoint BIG_BANG_TIME = 0; //can be time::now() later too static constexpr float UNIT_TIME = 1.0f; //in terms of human world seconds diff --git a/includes/entity.hpp b/includes/entity.hpp index c437e12..d0ab10f 100644 --- a/includes/entity.hpp +++ b/includes/entity.hpp @@ -11,6 +11,10 @@ #include "id_creator.hpp" #include "graphMat/3d_graph_box.hpp" // for Graph_Box +#ifdef DEBUG +#include +#endif // DEBUG + typedef void (*Action_Ptr)(void); struct Prop{ // @future - See the @future comment on the Entity::getUniqProp() function @@ -61,6 +65,9 @@ class Entity: public _ID{ _ID(), type(type) { +#ifdef DEBUG + std::cout << "New Entity; ID:" << this->_id << '\n'; +#endif // supported_Operations.push_back( &foo ); //works, void(void) in global scope // supported_Operations.push_back( &Entity::_Action1 ); //doesn't work // supported_Operations.push_back( &Entity::_Action1 ); //doesn't work diff --git a/includes/id_creator.hpp b/includes/id_creator.hpp index a44a811..acdd85a 100644 --- a/includes/id_creator.hpp +++ b/includes/id_creator.hpp @@ -4,7 +4,7 @@ #include "util/random.hpp" -typedef unsigned short id_type; +typedef unsigned int id_type; // @todo - Ensure this is thread_safe, to concurrently create multiple entities in different worlds IN DIFFERENT VERSES class _ID{ // no reuse of IDs, since it's enough public: @@ -12,5 +12,5 @@ class _ID{ // no reuse of IDs, since it's enough _ID(): _id(++(_ID::_curr_ID)){} id_type getId() const noexcept { return this->_id; } private: - static inline std::atomic _curr_ID{0}; + static inline std::atomic _curr_ID{111110}; }; diff --git a/includes/world_plot.hpp b/includes/world_plot.hpp index 36fe7b5..ec00420 100644 --- a/includes/world_plot.hpp +++ b/includes/world_plot.hpp @@ -38,13 +38,12 @@ class WorldPlot: public Cube_Matrix{ Path_Finder path_finder; Food food; // @future - food may have different points/nutitional values too - float free_space_ratio{100.0f}; void auto_expansion(); //keeps expanding TILL expansion_flag is TRUE void expand_once(); void resume_auto_expansion(); void pause_auto_expansion(); - dimen_t getFreeSpace() const; + float getFreeSpaceRatio() const; graph_box_type* get_box(const coord& position) { return this->operator[](position); } diff --git a/src/Entities/human.cpp b/src/Entities/human.cpp index 907a351..a4d20a6 100644 --- a/src/Entities/human.cpp +++ b/src/Entities/human.cpp @@ -45,6 +45,10 @@ Human::Human(World_Ptr const world): parent_world(world), curr_pos(nullptr, world->world_plot.getRandomCoord()) { +#ifdef DEBUG + std::cout << "=============================\nHuman aa gaya :D ... Location: [" << this->curr_pos.point_coord << "]\n=============================\n"; +#endif // DEBUG + this->curr_pos.graph_box = this->parent_world->get_box(curr_pos.point_coord); assert(curr_pos.graph_box != nullptr); // remove this assert after tests written that getRandomCoord() always returns correct one } diff --git a/src/Entities/rock.cpp b/src/Entities/rock.cpp index e580959..4a76db1 100644 --- a/src/Entities/rock.cpp +++ b/src/Entities/rock.cpp @@ -4,6 +4,10 @@ Rock::Rock(World_Ptr world) : Rock(world, world->world_plot.getRandomCoord()) {} Rock::Rock(World_Ptr world, const coord& location): Entity(Entity_Types::ROCK), location(world->world_plot[location], location) { +#ifdef DEBUG + std::cout << "Rock placed at location: " << this->location.point_coord << "\n"; +#endif + assert(this->location.graph_box != nullptr); // ie. we received valid coordinate, AND that coordinate is still in matrix this->location.graph_box->getDataRef().addEntity(this); diff --git a/src/Entities/snake.cpp b/src/Entities/snake.cpp index f7bc5af..f8c126d 100644 --- a/src/Entities/snake.cpp +++ b/src/Entities/snake.cpp @@ -210,7 +210,11 @@ Snake::Snake(const World_Ptr world, uint16_t init_len) : this->tail.point_coord = this->head.point_coord; this->tail.graph_box = this->head.graph_box; do { +#ifdef DEBUG + if (this->body.length() > 0) std::cout << "Clearing Snake: " << this->_id << '\n'; +#endif // DEBUG this->body.removeAndClearBody(); // we are repeating this over and over again, till we have okay body, that's why we are doing this + auto* prev_box = this->head.graph_box; for (auto i = 0; i < init_len - 1; i++) { // @future @note @me - The earlier implementation used randomly getting directions, then add_dir_to_coord neighbours @@ -231,7 +235,9 @@ Snake::Snake(const World_Ptr world, uint16_t init_len) : prev_box->getDataRef().addEntity(this); this->body.body.push_back(iter._getLastTurnedDirection().value()); // getLastTurnedDirection() MUST have a value +#ifdef DEBUG std::clog << "Added unit to snake's body: " << this->_id << '\n'; +#endif this->tail.graph_box = prev_box; this->tail.point_coord += iter._getIncrementCoords(); diff --git a/src/world.cpp b/src/world.cpp index d3d1f10..1c616fc 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -19,6 +19,11 @@ #include #include +// Entities +#include "Entities/snake.hpp" +#include "Entities/rock.hpp" +#include "Entities/human.hpp" + // inlining this function gives Unresolved External Symbol to call to this EXACT function in World_Node's constructor _timePoint World::getCurrentTime() const noexcept { @@ -77,14 +82,36 @@ World::World() : simulationRunning(false), world_plot(this, statics::BIG_BANG_TI this->entities.reserve(this->_MAX_NumSnakes); for (auto i = 0; i < this->_MAX_NumSnakes; i++) { - this->entities.push_back( //later when simulated, let all entities run on a different thread - new Snake(this, util::Random::random(2, 5)) + this->entities.push_back( + new Snake(this, util::Random::random(5, 10)) + ); + } + for (auto i = 0; i < 100; i++) + { + this->entities.push_back( + new Rock(this) + ); + } + for (auto i = 0; i < 2; i++) + { + this->entities.push_back( + new Human(this) ); } - // DEBUG - Disabled existence for now - //for (auto&& snake : this->snakes) { - // std::thread(&Snake::simulateExistence, snake).detach(); + //for (auto&& entity : this->entities) { + // switch (entity->type) + // { + // case Entity_Types::SNAKE: + // std::thread(&Snake::simulateExistence, entity).detach(); + // break; + // case Entity_Types::ROCK: + // std::thread(&Rock::simulateExistence, entity).detach(); + // break; + // case Entity_Types::HUMAN: + // std::thread(&Human::simulateExistence, entity).detach(); + // break; + // } //} // COME HERE - Decide how is time incremented diff --git a/src/world_plot.cpp b/src/world_plot.cpp index 657add7..e59340d 100644 --- a/src/world_plot.cpp +++ b/src/world_plot.cpp @@ -140,7 +140,7 @@ void WorldPlot::auto_expansion(){ while (this->__expansion_state.expansion_flag) { - std::clog << "Expanding...\n"; + std::clog << "UNIVERSE #" << this->parent_world->_id << " EXPANDING...\n"; this->expand_once(); // sleep for 1 unit time @@ -166,23 +166,27 @@ void WorldPlot::pause_auto_expansion() } // not actually number of nodes empty, but a utility function for WorldPlot::expand_once() -WorldPlot::dimen_t WorldPlot::getFreeSpace() const{ +float WorldPlot::getFreeSpaceRatio() const{ dimen_t min_x{ std::numeric_limits::max() }, max_x{ std::numeric_limits::min() }, min_y{ std::numeric_limits::max() }, - max_y{ std::numeric_limits::min() }; + max_y{ std::numeric_limits::min() }, + min_z{ std::numeric_limits::max() }, + max_z{ std::numeric_limits::min() }; - for (auto& snake : this->parent_world->entities) + for (auto& entity : this->parent_world->entities) { - if (snake->type != Entity_Types::SNAKE) continue; - - min_x = std::min(static_cast(snake)->getHead().point_coord.mX, min_x); - max_x = std::max(static_cast(snake)->getHead().point_coord.mX, max_x); - min_y = std::min(static_cast(snake)->getHead().point_coord.mX, min_y); - max_y = std::max(static_cast(snake)->getHead().point_coord.mX, max_y); + if (entity->type != Entity_Types::SNAKE) continue; + + min_x = std::min(entity->getPrimaryPos().value().point_coord.mX, min_x); + max_x = std::max(entity->getPrimaryPos().value().point_coord.mX, max_x); + min_y = std::min(entity->getPrimaryPos().value().point_coord.mY, min_y); + max_y = std::max(entity->getPrimaryPos().value().point_coord.mY, max_y); + min_z = std::min(entity->getPrimaryPos().value().point_coord.mZ, min_z); + max_z = std::max(entity->getPrimaryPos().value().point_coord.mZ, max_z); } - return (this->getOrder() * this->getOrder()) - ( (max_x - min_x)*(max_y - min_y) ); + return 100.0f - (((static_cast(max_x) - min_x)* (max_y - min_y)* (max_z - min_z))/(this->total_abs.mX * total_abs.mY * total_abs.mZ)); } // @note - The function decides how much to grow, and may decide to not grow at all "for this call" @@ -190,21 +194,23 @@ void WorldPlot::expand_once(){ // `may` expands one unit on each side constexpr float decrease_rate = 0.90f; // 90% of previous expansion speed - this->free_space_ratio = static_cast(this->getFreeSpace())/this->getOrder(); + const auto free_space_ratio = this->getFreeSpaceRatio(); // @future [Oct22] - The below does the speed resetting part, change it to allow negative expansions if (this->__expansion_state.time_since_speed_updated % 10 == 0) { + this->__expansion_state.speed_doubled_recently = false; this->__expansion_state.curr_expansion_speed = this->__expansion_state.expansion_speed; this->__expansion_state.time_since_speed_updated = 0; } - if ( this->free_space_ratio > statics::max_free_space ){ + if ( free_space_ratio > statics::max_free_space ){ // @log - world doesn't need to auto_expand since reached max_free_space return; - }else if ( this->free_space_ratio < statics::min_free_space ) + }else if ( free_space_ratio < statics::min_free_space && !this->__expansion_state.speed_doubled_recently) { this->__expansion_state.curr_expansion_speed *= 2; // @log temporarily doubling the expansion speed + this->__expansion_state.speed_doubled_recently = true; } else { this->__expansion_state.curr_expansion_speed *= decrease_rate;