Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "geo2d.h"
- #include "game_object.h"
- #include "test_runner.h"
- #include <vector>
- #include <memory>
- using namespace std;
- template <typename T>
- struct Collider : GameObject {
- bool Collide(const GameObject& that) const final {
- // Статически приводим тип *this к типу const T&, потому что мы знаем,
- // что T — наш наследник (см. ниже)
- return that.CollideWith(static_cast<const T&>(*this));
- }
- };
- class Unit final : public Collider<Unit>{
- geo2d::Point geometry;
- public:
- Unit(geo2d::Point position):geometry(position) {}
- geo2d::Point GetGeometry() const
- {
- return geometry;
- } // .
- // Переопределения методов CollideWith — метод Collide переопределять уже не нужно
- bool CollideWith(const Unit& that) const override{ return geo2d::Collide(geometry, that.GetGeometry()); }
- bool CollideWith(const Building& that) const override { return geo2d::Collide(geometry, that.GetGeometry()); }
- bool CollideWith(const Tower& that) const override { return geo2d::Collide(geometry, that.GetGeometry()); }
- bool CollideWith(const Fence& that) const override { return geo2d::Collide(geometry, that.GetGeometry()); }
- };
- class Building final : public Collider<Building> {
- geo2d::Rectangle geometry;
- public:
- explicit Building(geo2d::Rectangle geometry):geometry(geometry){}
- geo2d::Rectangle GetGeometry() const
- {
- return geometry;
- }
- bool CollideWith(const Unit& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
- bool CollideWith(const Building& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
- bool CollideWith(const Tower& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
- bool CollideWith(const Fence& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
- };
- class Tower final : public Collider<Tower> {
- geo2d::Circle geometry;
- public:
- geo2d::Circle GetGeometry() const
- {
- return geometry;
- }
- explicit Tower(geo2d::Circle geometry) :geometry(geometry) {}
- bool CollideWith(const Unit& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
- bool CollideWith(const Building& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
- bool CollideWith(const Tower& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
- bool CollideWith(const Fence& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
- };
- class Fence final : public Collider<Fence> {
- geo2d::Segment geometry;
- public:
- explicit Fence(geo2d::Segment geometry) :geometry(geometry) {}
- geo2d::Segment GetGeometry() const
- {
- return geometry;
- }
- bool CollideWith(const Unit& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
- bool CollideWith(const Building& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
- bool CollideWith(const Tower& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
- bool CollideWith(const Fence& that) const { return geo2d::Collide(geometry, that.GetGeometry()); }
- };
- // Реализуйте функцию Collide из файла GameObject.h
- bool Collide(const GameObject& first, const GameObject& second)
- {
- return first.Collide(second);
- }
- void TestAddingNewObjectOnMap() {
- // Юнит-тест моделирует ситуацию, когда на игровой карте уже есть какие-то объекты,
- // и мы хотим добавить на неё новый, например, построить новое здание или башню.
- // Мы можем его добавить, только если он не пересекается ни с одним из существующих.
- using namespace geo2d;
- const vector<shared_ptr<GameObject>> game_map = {
- make_shared<Unit>(Point{3, 3}),
- make_shared<Unit>(Point{5, 5}),
- make_shared<Unit>(Point{3, 7}),
- make_shared<Fence>(Segment{{7, 3}, {9, 8}}),
- make_shared<Tower>(Circle{Point{9, 4}, 1}),
- make_shared<Tower>(Circle{Point{10, 7}, 1}),
- make_shared<Building>(Rectangle{{11, 4}, {14, 6}})
- };
- for (size_t i = 0; i < game_map.size(); ++i) {
- Assert(
- Collide(*game_map[i], *game_map[i]),
- "An object doesn't collide with itself: " + to_string(i)
- );
- for (size_t j = 0; j < i; ++j) {
- Assert(
- !Collide(*game_map[i], *game_map[j]),
- "Unexpected collision found " + to_string(i) + ' ' + to_string(j)
- );
- }
- }
- auto new_warehouse = make_shared<Building>(Rectangle{ {4, 3}, {9, 6} });
- ASSERT(!Collide(*new_warehouse, *game_map[0]));
- ASSERT(Collide(*new_warehouse, *game_map[1]));
- ASSERT(!Collide(*new_warehouse, *game_map[2]));
- ASSERT(Collide(*new_warehouse, *game_map[3]));
- ASSERT(Collide(*new_warehouse, *game_map[4]));
- ASSERT(!Collide(*new_warehouse, *game_map[5]));
- ASSERT(!Collide(*new_warehouse, *game_map[6]));
- auto new_defense_tower = make_shared<Tower>(Circle{ {8, 2}, 2 });
- ASSERT(!Collide(*new_defense_tower, *game_map[0]));
- ASSERT(!Collide(*new_defense_tower, *game_map[1]));
- ASSERT(!Collide(*new_defense_tower, *game_map[2]));
- ASSERT(Collide(*new_defense_tower, *game_map[3]));
- ASSERT(Collide(*new_defense_tower, *game_map[4]));
- ASSERT(!Collide(*new_defense_tower, *game_map[5]));
- ASSERT(!Collide(*new_defense_tower, *game_map[6]));
- }
- int main() {
- TestRunner tr;
- RUN_TEST(tr, TestAddingNewObjectOnMap);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement