#include #include #include #include #include #include #include class Ammunition { public: Ammunition(size_t amount) : _amount(amount) {} virtual ~Ammunition() = default; virtual void fire() = 0; virtual void draw() = 0; virtual int getDamage() const = 0; size_t amount() const { return _amount; } private: size_t _amount = 0; }; class FireStrategy { public: virtual void fire(const Ammunition& ammunition) = 0; }; class SDLFireStrategy : public FireStrategy { public: void fire(const Ammunition& ammunition) override { std::cout << "SDL Deal: " << ammunition.getDamage() << " damage!" << '\n'; } }; class WAMFireStrategy : public FireStrategy { public: void fire(const Ammunition& ammunition) override { std::cout << "WAM Deal: " << ammunition.getDamage() << " damage!" << '\n'; } }; class DrawStrategy { public: virtual void draw(const Ammunition& ammunition) = 0; }; class OpenGLDrawStrategy : public DrawStrategy { public: void draw(const Ammunition& ammunition) override { std::cout << "OpenGL Ammunition: " << ammunition.amount() << '\n'; } }; class MetalDrawStrategy : public DrawStrategy { public: void draw(const Ammunition& ammunition) override { std::cout << "Metal Ammunition: " << ammunition.amount() << '\n'; } }; class RoundShot : public Ammunition { public: RoundShot(size_t amount, std::unique_ptr&& fireStrategy, std::unique_ptr&& drawStrategy) : Ammunition(amount), _fireStrategy(std::move(fireStrategy)), _drawStrategy(std::move(drawStrategy)) {} void fire() override { _fireStrategy->fire(*this /* other args if needed*/); } void draw() override { _drawStrategy->draw(*this /* other args if needed*/); } int getDamage() const override { return 10; } private: std::unique_ptr _fireStrategy; std::unique_ptr _drawStrategy; }; class ChainShot : public Ammunition { public: ChainShot(size_t amount, std::unique_ptr&& fireStrategy, std::unique_ptr&& drawStrategy) : Ammunition(amount), _fireStrategy(std::move(fireStrategy)), _drawStrategy(std::move(drawStrategy)) {} void fire() override { _fireStrategy->fire(*this /* other args if needed*/); } void draw() override { _drawStrategy->draw(*this /* other args if needed*/); } int getDamage() const override { return 15; } private: std::unique_ptr _fireStrategy; std::unique_ptr _drawStrategy; }; class GrapeShot : public Ammunition { public: GrapeShot(size_t amount, std::unique_ptr&& fireStrategy, std::unique_ptr&& drawStrategy) : Ammunition(amount), _fireStrategy(std::move(fireStrategy)), _drawStrategy(std::move(drawStrategy)) {} void fire() override { _fireStrategy->fire(*this /* other args if needed*/); } void draw() override { _drawStrategy->draw(*this /* other args if needed*/); } int getDamage() const override { return 20; } private: std::unique_ptr _fireStrategy; std::unique_ptr _drawStrategy; }; int main() { std::unique_ptr grapeShot = std::make_unique( 100, std::make_unique(), std::make_unique()); grapeShot->fire(); grapeShot->draw(); }