Advertisement
syxstep

Untitled

Feb 29th, 2020
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.91 KB | None | 0 0
  1. #include "geo2d.h"
  2. #include "game_object.h"
  3.  
  4. #include "test_runner.h"
  5.  
  6. #include <vector>
  7. #include <memory>
  8.  
  9. using namespace std;
  10.  
  11.  
  12. template <typename T>
  13. struct Collider : GameObject {
  14.  
  15.     bool Collide(const GameObject& that) const final {
  16.         // Статически приводим тип *this к типу const T&, потому что мы знаем,
  17.         // что T — наш наследник (см. ниже)
  18.         return that.CollideWith(static_cast<const T&>(*this));
  19.     }
  20. };
  21.  
  22. class Unit  final : public Collider<Unit>{
  23.     geo2d::Point geometry;
  24.  
  25. public:
  26.     Unit(geo2d::Point position):geometry(position) {}
  27.     geo2d::Point GetGeometry() const
  28.     {
  29.         return geometry;
  30.     }   // .
  31.     // Переопределения методов CollideWith — метод Collide переопределять уже не нужно
  32.      bool CollideWith(const Unit& that) const override{ return geo2d::Collide(geometry, that.GetGeometry()); }
  33.      bool CollideWith(const Building& that) const override { return geo2d::Collide(geometry, that.GetGeometry()); }
  34.      bool CollideWith(const Tower& that) const override { return geo2d::Collide(geometry, that.GetGeometry()); }
  35.      bool CollideWith(const Fence& that) const override { return geo2d::Collide(geometry, that.GetGeometry()); }
  36.  
  37. };
  38.  
  39. class Building final : public Collider<Building> {
  40.     geo2d::Rectangle geometry;
  41. public:
  42.  
  43.     explicit Building(geo2d::Rectangle geometry):geometry(geometry){}
  44.     geo2d::Rectangle GetGeometry() const
  45.     {
  46.         return geometry;
  47.     }
  48.      bool CollideWith(const Unit& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
  49.      bool CollideWith(const Building& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
  50.      bool CollideWith(const Tower& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
  51.      bool CollideWith(const Fence& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
  52.  
  53. };
  54.  
  55. class Tower final : public Collider<Tower> {
  56.     geo2d::Circle geometry;
  57.  
  58.  
  59. public:
  60.     geo2d::Circle GetGeometry() const
  61.     {
  62.         return geometry;
  63.     }
  64.  
  65.     explicit Tower(geo2d::Circle geometry) :geometry(geometry) {}
  66.      bool CollideWith(const Unit& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
  67.      bool CollideWith(const Building& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
  68.      bool CollideWith(const Tower& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
  69.      bool CollideWith(const Fence& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
  70.  
  71. };
  72.  
  73. class Fence final : public Collider<Fence> {
  74.     geo2d::Segment geometry;
  75. public:
  76.    
  77.    
  78.     explicit Fence(geo2d::Segment geometry) :geometry(geometry) {}
  79.     geo2d::Segment GetGeometry() const
  80.     {
  81.         return geometry;
  82.     }
  83.      bool CollideWith(const Unit& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
  84.      bool CollideWith(const Building& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
  85.      bool CollideWith(const Tower& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
  86.      bool CollideWith(const Fence& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
  87. };
  88.  
  89. // Реализуйте функцию Collide из файла GameObject.h
  90.  
  91. bool Collide(const GameObject& first, const GameObject& second)
  92. {
  93.  
  94.     return first.Collide(second);
  95. }
  96.  
  97. void TestAddingNewObjectOnMap() {
  98.     // Юнит-тест моделирует ситуацию, РєРѕРіРґР° РЅР° РёРіСЂРѕРІРѕР№ карте уже есть какие-то объекты,
  99.     // Рё РјС‹ хотим добавить РЅР° неё новый, например, построить РЅРѕРІРѕРµ здание или башню.
  100.     // РњС‹ можем его добавить, только если РѕРЅ РЅРµ пересекается РЅРё СЃ РѕРґРЅРёРј РёР· существующих.
  101.     using namespace geo2d;
  102.  
  103.     const vector<shared_ptr<GameObject>> game_map = {
  104.       make_shared<Unit>(Point{3, 3}),
  105.       make_shared<Unit>(Point{5, 5}),
  106.       make_shared<Unit>(Point{3, 7}),
  107.       make_shared<Fence>(Segment{{7, 3}, {9, 8}}),
  108.       make_shared<Tower>(Circle{Point{9, 4}, 1}),
  109.       make_shared<Tower>(Circle{Point{10, 7}, 1}),
  110.       make_shared<Building>(Rectangle{{11, 4}, {14, 6}})
  111.     };
  112.  
  113.     for (size_t i = 0; i < game_map.size(); ++i) {
  114.         Assert(
  115.             Collide(*game_map[i], *game_map[i]),
  116.             "An object doesn't collide with itself: " + to_string(i)
  117.         );
  118.  
  119.         for (size_t j = 0; j < i; ++j) {
  120.             Assert(
  121.                 !Collide(*game_map[i], *game_map[j]),
  122.                 "Unexpected collision found " + to_string(i) + ' ' + to_string(j)
  123.             );
  124.         }
  125.     }
  126.  
  127.     auto new_warehouse = make_shared<Building>(Rectangle{ {4, 3}, {9, 6} });
  128.     ASSERT(!Collide(*new_warehouse, *game_map[0]));
  129.     ASSERT(Collide(*new_warehouse, *game_map[1]));
  130.     ASSERT(!Collide(*new_warehouse, *game_map[2]));
  131.     ASSERT(Collide(*new_warehouse, *game_map[3]));
  132.     ASSERT(Collide(*new_warehouse, *game_map[4]));
  133.     ASSERT(!Collide(*new_warehouse, *game_map[5]));
  134.     ASSERT(!Collide(*new_warehouse, *game_map[6]));
  135.  
  136.     auto new_defense_tower = make_shared<Tower>(Circle{ {8, 2}, 2 });
  137.     ASSERT(!Collide(*new_defense_tower, *game_map[0]));
  138.     ASSERT(!Collide(*new_defense_tower, *game_map[1]));
  139.     ASSERT(!Collide(*new_defense_tower, *game_map[2]));
  140.     ASSERT(Collide(*new_defense_tower, *game_map[3]));
  141.     ASSERT(Collide(*new_defense_tower, *game_map[4]));
  142.     ASSERT(!Collide(*new_defense_tower, *game_map[5]));
  143.     ASSERT(!Collide(*new_defense_tower, *game_map[6]));
  144. }
  145.  
  146. int main() {
  147.     TestRunner tr;
  148.     RUN_TEST(tr, TestAddingNewObjectOnMap);
  149.     return 0;
  150. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement