diff options
| author | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:08:27 +0200 |
|---|---|---|
| committer | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:08:27 +0200 |
| commit | c9b6b9a5ca082fe7c1b6f58d7713f785a9eb6a5c (patch) | |
| tree | 3e4f42f93c7ae89a364e4d51fff6e5cec4e55fa9 /graphs/cpp/caste_or_cast/colony.cc | |
add: graphs et rushs
Diffstat (limited to 'graphs/cpp/caste_or_cast/colony.cc')
| -rw-r--r-- | graphs/cpp/caste_or_cast/colony.cc | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/graphs/cpp/caste_or_cast/colony.cc b/graphs/cpp/caste_or_cast/colony.cc new file mode 100644 index 0000000..2c0697a --- /dev/null +++ b/graphs/cpp/caste_or_cast/colony.cc @@ -0,0 +1,116 @@ +#include "colony.hh" + +#include <iostream> + +#include "nurturer.hh" +#include "provider.hh" + +Colony::Colony(uint32_t passport) + : passport_pheromone_(passport) + , workers_() +{} +bool Colony::addAnt(const Ant& ant, std::shared_ptr<Colony> colony) +{ + auto q = dynamic_cast<const Queen*>(&ant); + if (q) + { + if (colony->queen_ || q->get_stage() != DevelopmentStage::ADULT) + return false; + colony->queen_ = std::make_unique<Queen>(*q); + return true; + } + auto n = dynamic_cast<const Nurturer*>(&ant); + if (n) + { + colony->workers_.push_back(std::make_shared<Nurturer>(*n)); + return true; + } + auto p = dynamic_cast<const Provider*>(&ant); + if (p) + { + colony->workers_.push_back(std::make_shared<Provider>(*p)); + return true; + } + return false; +} + +void Colony::manageQueen() +{ + if (queen_ == nullptr) + throw std::runtime_error("Cannot manage a colony without a Queen."); + // check if the queen should lose health points + if (queen_->food_level_ < 0) + queen_->hp_ -= 1; + if (queen_->hp_ <= 0) + { + queen_ = nullptr; + throw std::runtime_error("The Queen died."); + } + // Append to workers_ all the new workers contained in the queen's + // eggs_queue_ + while (!queen_->eggs_queue_.empty()) + { + //! we insert eggs that were laid by the queen + workers_.emplace_back(queen_->eggs_queue_.front()); + queen_->eggs_queue_.pop(); + } +} + +void Colony::removeDeadWorkers() +{ + auto dead_count = std::erase_if( + workers_, [](const std::shared_ptr<Worker> w) { return w->hp_ <= 0; }); + if (dead_count > 0) + { + std::cout << dead_count << " workers_ died.\n"; + // each dead worker decrease the cleanliness of the colony + cleanliness -= 0.5 * dead_count; + } +} + +// this method can be considered as one round of management +void Colony::manageAnts() +{ + // We first manage the queen + manageQueen(); + // We remove all dead workers contained in workers_ + removeDeadWorkers(); + std::cout << "-- THERE ARE " << workers_.size() << " WORKERS --\n"; + // We iterate over all workers + for (auto worker : workers_) + { + if (worker->stage_ == DevelopmentStage::ADULT) + { + /* + * Because work() is a virtual method, dynamic dispatch will be + * used. Which means that the overridden work method of the true + * type (either Nurturer or Provider) will actually be called + * instead of Worker::work(). + */ + worker->work(); + } + else + { + /* + * We increment their food_level_ as if it is a ticking time, + * EXCEPT for the larvae, as they are fed by nurturers. + */ + if (worker->stage_ != DevelopmentStage::LARVA) + worker->food_level_ += 1; + if (worker->food_level_ >= 4.0) + { + /* FIXME : Make the worker change stage_ and reset their + * food_level_ to 0. HINT : This can take only 2/3 lines if + * you use a certain C++ cast instead of a switch. + */ + worker->food_level_ = 0; + auto ant = static_cast<Ant*>(worker.get()); + ant->stage_ = static_cast<DevelopmentStage>( + static_cast<int>(ant->stage_) + 1); + } + } + } + queen_->food_level_ -= 0.2; +} + +// FIXME : Implements addAnt() static method. |
