#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 ChainShot; class RoundShot; class GrapeShot; class FireStrategy { public: virtual void fire(const ChainShot& shot) = 0; virtual void fire(const RoundShot& shot) = 0; virtual void fire(const GrapeShot& shot) = 0; }; class SDLFireStrategy : public FireStrategy { public: void fire(const ChainShot& shot) override; void fire(const RoundShot& shot) override; void fire(const GrapeShot& shot) override; }; class WAMFireStrategy : public FireStrategy { public: void fire(const ChainShot& shot) override; void fire(const RoundShot& shot) override; void fire(const GrapeShot& shot) override; }; class DrawStrategy { public: virtual void draw(const ChainShot& shot) = 0; virtual void draw(const RoundShot& shot) = 0; virtual void draw(const GrapeShot& shot) = 0; }; class OpenGLDrawStrategy : public DrawStrategy { public: void draw(const ChainShot& shot) override; void draw(const RoundShot& shot) override; void draw(const GrapeShot& shot) override; }; class MetalDrawStrategy : public DrawStrategy { public: void draw(const ChainShot& shot) override; void draw(const RoundShot& shot) override; void draw(const GrapeShot& shot) override; }; 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; }; void SDLFireStrategy::fire(const ChainShot& shot) { std::cout << "SDL Chain Shot Deal: " << shot.getDamage() << " damage!" << '\n'; } void SDLFireStrategy::fire(const RoundShot& shot) { std::cout << "SDL Round Shot Deal: " << shot.getDamage() << " damage!" << '\n'; } void SDLFireStrategy::fire(const GrapeShot& shot) { std::cout << "SDL Grape Shot Deal: " << shot.getDamage() << " damage!" << '\n'; } void WAMFireStrategy::fire(const ChainShot& shot) { std::cout << "WAM Chain Shot Deal: " << shot.getDamage() << " damage!" << '\n'; } void WAMFireStrategy::fire(const RoundShot& shot) { std::cout << "WAM Round Shot Deal: " << shot.getDamage() << " damage!" << '\n'; } void WAMFireStrategy::fire(const GrapeShot& shot) { std::cout << "WAM Grape Shot Deal: " << shot.getDamage() << " damage!" << '\n'; } void OpenGLDrawStrategy::draw(const ChainShot& shot) { std::cout << "OpenGL Chain Shot: " << shot.amount() << '\n'; } void OpenGLDrawStrategy::draw(const RoundShot& shot) { std::cout << "OpenGL Round Shot: " << shot.amount() << '\n'; } void OpenGLDrawStrategy::draw(const GrapeShot& shot) { std::cout << "OpenGL Grape Shot: " << shot.amount() << '\n'; } void MetalDrawStrategy::draw(const ChainShot& shot) { std::cout << "Metal Chain Shot: " << shot.amount() << '\n'; } void MetalDrawStrategy::draw(const RoundShot& shot) { std::cout << "Metal Round Shot: " << shot.amount() << '\n'; } void MetalDrawStrategy::draw(const GrapeShot& shot) { std::cout << "Metal Grape Shot: " << shot.amount() << '\n'; } int main() { std::unique_ptr grapeShot = std::make_unique( 100, std::make_unique(), std::make_unique()); grapeShot->fire(); grapeShot->draw(); }