fork download
  1. #include <iostream>
  2. #include <memory>
  3. #include <vector>
  4. #include <algorithm>
  5.  
  6. using namespace std;
  7.  
  8. class Animal
  9. {
  10. public:
  11. using Pointer = unique_ptr<Animal>;
  12.  
  13. public:
  14. struct Point{ Point(double x, double y) : mX{x}, mY{y}{} double mX, mY; };
  15.  
  16. public:
  17. Animal(char id, Point position) : mId{id}, mPosition{position}{}
  18.  
  19. ~Animal()
  20. {
  21. destroy();
  22. }
  23.  
  24. void attackEnemy(Animal* enemy)
  25. {
  26. mEnemyTarget = enemy;
  27. enemy->addEnemyAttacker(this);
  28. }
  29.  
  30. void destroy()
  31. {
  32. cout << mId << " is destroyed!" << endl;
  33. if(mEnemyTarget) mEnemyTarget->notifyEnemyAttackerIsDown(this);
  34. for_each(mEnemyAttackers.begin(), mEnemyAttackers.end(), mem_fn(&Animal::notifyEnemyTargetIsDown));
  35. }
  36.  
  37. char getId() const
  38. {
  39. return mId;
  40. }
  41.  
  42. const Point* getPosition() const
  43. {
  44. return &mPosition;
  45. }
  46.  
  47. void whatAttack() const
  48. {
  49. cout << mId << " attack: " << (mEnemyTarget ? (mEnemyTarget->getId() + string(" ") + to_string(mEnemyTarget->getPosition()->mX) + ' ' + to_string(mEnemyTarget->getPosition()->mY)) : "nothing") << endl;
  50. }
  51.  
  52. private:
  53. void addEnemyAttacker(Animal* enemyAttacker)
  54. {
  55. mEnemyAttackers.push_back(enemyAttacker);
  56. }
  57.  
  58. void notifyEnemyAttackerIsDown(Animal* enemyAttacker)
  59. {
  60. mEnemyAttackers.erase(remove_if(mEnemyAttackers.begin(), mEnemyAttackers.end(), [enemyAttacker](Animal* attacker) { return attacker == enemyAttacker; }), mEnemyAttackers.end());
  61. }
  62.  
  63. void notifyEnemyTargetIsDown()
  64. {
  65. mEnemyTarget = nullptr;
  66. }
  67.  
  68. private:
  69. char mId;
  70. Point mPosition;
  71. Animal* mEnemyTarget{nullptr};
  72. vector<Animal*> mEnemyAttackers;
  73. };
  74.  
  75. int main()
  76. {
  77. Animal::Pointer a{new Animal{'A', {0, 0}}};
  78. Animal::Pointer b{new Animal{'B', {0, 0}}};
  79.  
  80. a->whatAttack();
  81. b->whatAttack();
  82.  
  83. {
  84. Animal::Pointer c{new Animal{'C', {5, 5}}};
  85.  
  86. a->attackEnemy(c.get());
  87. b->attackEnemy(c.get());
  88. a->whatAttack();
  89. b->whatAttack();
  90.  
  91. // C w miedzyczasie ginie z niewiadomych powodów
  92. }
  93.  
  94. a->whatAttack(); // ok
  95. b->whatAttack(); // ok
  96. }
  97.  
Success #stdin #stdout 0s 3232KB
stdin
Standard input is empty
stdout
A attack: nothing
B attack: nothing
A attack: C 5.000000 5.000000
B attack: C 5.000000 5.000000
C is destroyed!
A attack: nothing
B attack: nothing
B is destroyed!
A is destroyed!