Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -----------------------------------------------------------------------
- people.h
- -----------------------------------------------------------------------
- #pragma once
- #include <string>
- class Person;
- class PersonObserver {
- public:
- virtual void OnSatisfactionChanged(Person&, int, int) {}
- protected:
- ~PersonObserver() = default;
- };
- class Person {
- public:
- Person(const std::string& name, int age) : name_(name),
- age_(age) {}
- virtual ~Person() = default;
- const std::string& GetName() const {
- return name_;
- }
- int GetAge() const {
- return age_;
- }
- int GetSatisfaction() const {
- return satisfaction_;
- }
- auto GetObserver() const {
- return observer_;
- }
- void SetObserver(PersonObserver* observer) {
- observer_ = observer;
- }
- virtual void Dance() {
- ++dance_count_;
- SetSatisfaction(satisfaction_ + 1);
- }
- int GetDanceCount() const {
- return dance_count_;
- }
- virtual void LiveADay() {}
- protected:
- virtual void SetSatisfaction(int value) {
- if (satisfaction_ != value) {
- int old_value = satisfaction_;
- satisfaction_ = value;
- if (observer_) {
- observer_->OnSatisfactionChanged(*this, old_value, satisfaction_);
- }
- }
- }
- private:
- std::string name_;
- int age_;
- int satisfaction_ = 100;
- PersonObserver* observer_ = nullptr;
- int dance_count_ = 0;
- };
- class Worker : public Person {
- public:
- Worker(const std::string& name, int age) : Person(name, age) {}
- void Dance() override {
- Person::Dance();
- if (int age = GetAge(); age > 30 && age < 40) {
- SetSatisfaction(GetSatisfaction() + 1);
- }
- }
- void Work() {
- ++work_;
- SetSatisfaction(GetSatisfaction() - 5);
- }
- int GetWorkDone() const {
- return work_;
- }
- void LiveADay() override {
- Work();
- }
- private:
- int work_ = 0;
- };
- class Student : public Person {
- public:
- Student(const std::string& name, int age) : Person(name, age) {}
- void Study() {
- ++study_;
- SetSatisfaction(GetSatisfaction() - 3);
- }
- void Dance() override {
- auto old_value = GetSatisfaction();
- Person::Dance();
- if (GetObserver()) {
- GetObserver()->OnSatisfactionChanged(*this, old_value, GetSatisfaction());
- }
- }
- int GetKnowledgeLevel() const {
- return study_;
- }
- void LiveADay() override {
- Study();
- }
- private:
- int study_ = 0;
- };
- -----------------------------------------------------------------------
- supervisor.h
- -----------------------------------------------------------------------
- #pragma once
- #include "people.h"
- class SatisfactionSupervisor : public PersonObserver {
- public:
- SatisfactionSupervisor(int min_satisfaction, int max_satisfaction) : min_(min_satisfaction),
- max_(max_satisfaction) {}
- void OnSatisfactionChanged(Person& person, int old_value, int new_value) {
- if (new_value < min_ && (new_value - old_value) < 0) {
- while (person.GetSatisfaction() < max_) {
- person.Dance();
- }
- }
- }
- private:
- int min_ = 0;
- int max_ = 0;
- };
- -----------------------------------------------------------------------
- simulation.cpp
- -----------------------------------------------------------------------
- #include "people.h"
- #include "supervisor.h"
- #include <cassert>
- #include <iostream>
- #include <memory>
- #include <optional>
- #include <vector>
- using namespace std;
- void RunSimulation(vector<unique_ptr<Person>>& people, int num_days) {
- for (int i = 0; i < num_days; ++i) {
- for (auto& person : people) {
- person->LiveADay();
- }
- }
- }
- void Tests() {
- struct TestObserver : public PersonObserver {
- Person* person = nullptr;
- optional<int> old_satisfaction;
- optional<int> new_satisfaction;
- void OnSatisfactionChanged(Person& p, int old_value, int new_value) override {
- this->person = &p;
- this->old_satisfaction = old_value;
- this->new_satisfaction = new_value;
- }
- };
- {
- Person p{"Ivan"s, 30};
- assert(p.GetDanceCount() == 0);
- const int old_satisfaction = p.GetSatisfaction();
- assert(old_satisfaction == 100);
- p.Dance();
- assert(p.GetDanceCount() == 1);
- assert(p.GetSatisfaction() == old_satisfaction + 1);
- TestObserver o;
- p.SetObserver(&o);
- assert(o.person == nullptr);
- p.Dance();
- assert(o.person == &p);
- assert(o.old_satisfaction == old_satisfaction + 1);
- assert(o.new_satisfaction == old_satisfaction + 2);
- }
- {
- Worker w{"Ivan"s, 35};
- const int old_satisfaction = w.GetSatisfaction();
- assert(w.GetWorkDone() == 0);
- w.Work();
- assert(w.GetSatisfaction() == old_satisfaction - 5);
- assert(w.GetWorkDone() == 1);
- w.LiveADay();
- assert(w.GetSatisfaction() == old_satisfaction - 10);
- assert(w.GetWorkDone() == 2);
- assert(w.GetDanceCount() == 0);
- w.Dance();
- assert(w.GetDanceCount() == 1);
- assert(w.GetSatisfaction() == old_satisfaction - 10 + 2);
- }
- {
- Student s{"Ivan"s, 18};
- const int old_satisfaction = s.GetSatisfaction();
- assert(s.GetKnowledgeLevel() == 0);
- s.Study();
- assert(s.GetSatisfaction() == old_satisfaction - 3);
- assert(s.GetKnowledgeLevel() == 1);
- s.LiveADay();
- assert(s.GetSatisfaction() == old_satisfaction - 6);
- assert(s.GetKnowledgeLevel() == 2);
- assert(s.GetDanceCount() == 0);
- s.Dance();
- assert(s.GetDanceCount() == 1);
- assert(s.GetSatisfaction() == old_satisfaction - 6 + 1);
- }
- {
- Worker w("Ivan"s, 35);
- SatisfactionSupervisor sup{95, 97};
- w.SetObserver(&sup);
- w.Work();
- assert(w.GetSatisfaction() == 95);
- assert(w.GetDanceCount() == 0);
- w.Work();
- assert(w.GetDanceCount() == 4);
- assert(w.GetSatisfaction() == 98);
- }
- {
- struct DestructivePerson : public Person {
- explicit DestructivePerson(bool& destruction_flag)
- : Person("test"s, 20)
- , destruction_flag_(destruction_flag) {
- destruction_flag_ = false;
- }
- ~DestructivePerson() {
- destruction_flag_ = true;
- }
- bool& destruction_flag_;
- };
- bool person_destroyed = false;
- unique_ptr<Person> p = make_unique<DestructivePerson>(person_destroyed);
- assert(!person_destroyed);
- p.reset();
- assert(person_destroyed);
- }
- }
- int main() {
- Tests();
- vector<unique_ptr<Person>> people;
- people.emplace_back(make_unique<Worker>("Mario"s, 35));
- people.emplace_back(make_unique<Student>("Harry Potter"s, 18));
- SatisfactionSupervisor supervisor(90, 100);
- for (auto& person : people) {
- person->SetObserver(&supervisor);
- }
- RunSimulation(people, 10);
- for (auto& person : people) {
- cout << person->GetName() << "' satisfaction: "s << person->GetSatisfaction() << ", dance count: "s
- << person->GetDanceCount() << endl;
- }
- for (auto& person : people) {
- person->SetObserver(nullptr);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment