#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; template class FireStrategy { public: virtual void fire(const T& shot) = 0; }; class SDLFireRoundShotStrategy : public FireStrategy { public: void fire(const RoundShot& shot) override; }; class SDLFireChainShotStrategy : public FireStrategy { public: void fire(const ChainShot& shot) override; }; class SDLFireGrapeShotStrategy : public FireStrategy { public: void fire(const GrapeShot& shot) override; }; class WAMFireRoundShotStrategy : public FireStrategy { public: void fire(const RoundShot& shot) override; }; class WAMFirChainShotStrategy : public FireStrategy { public: void fire(const ChainShot& shot) override; }; class WAMFireGrapeShotStrategy : public FireStrategy { public: void fire(const GrapeShot& shot) override; }; template class DrawStrategy { public: virtual void draw(const T& shot) = 0; }; class OpenGLDrawRoundShotStrategy : public DrawStrategy { public: void draw(const RoundShot& shot) override; }; class OpenGLDrawChainShotStrategy : public DrawStrategy { public: void draw(const ChainShot& shot) override; }; class OpenGLDrawGrapeShotStrategy : public DrawStrategy { public: void draw(const GrapeShot& shot) override; }; class MetalDrawRoundShotStrategy : public DrawStrategy { public: void draw(const RoundShot& shot) override; }; class MetalDrawChainShotStrategy : public DrawStrategy { public: void draw(const ChainShot& shot) override; }; class MetalDrawGrapeShotStrategy : public DrawStrategy { public: 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 SDLFireChainShotStrategy::fire(const ChainShot& shot) { std::cout << "SDL Chain Shot Deal: " << shot.getDamage() << " damage!" << '\n'; } void SDLFireRoundShotStrategy::fire(const RoundShot& shot) { std::cout << "SDL Round Shot Deal: " << shot.getDamage() << " damage!" << '\n'; } void SDLFireGrapeShotStrategy::fire(const GrapeShot& shot) { std::cout << "SDL Grape Shot Deal: " << shot.getDamage() << " damage!" << '\n'; } void WAMFirChainShotStrategy::fire(const ChainShot& shot) { std::cout << "WAM Chain Shot Deal: " << shot.getDamage() << " damage!" << '\n'; } void WAMFireRoundShotStrategy::fire(const RoundShot& shot) { std::cout << "WAM Round Shot Deal: " << shot.getDamage() << " damage!" << '\n'; } void WAMFireGrapeShotStrategy::fire(const GrapeShot& shot) { std::cout << "WAM Grape Shot Deal: " << shot.getDamage() << " damage!" << '\n'; } void OpenGLDrawChainShotStrategy::draw(const ChainShot& shot) { std::cout << "OpenGL Chain Shot: " << shot.amount() << '\n'; } void OpenGLDrawRoundShotStrategy::draw(const RoundShot& shot) { std::cout << "OpenGL Round Shot: " << shot.amount() << '\n'; } void OpenGLDrawGrapeShotStrategy::draw(const GrapeShot& shot) { std::cout << "OpenGL Grape Shot: " << shot.amount() << '\n'; } void MetalDrawChainShotStrategy::draw(const ChainShot& shot) { std::cout << "Metal Chain Shot: " << shot.amount() << '\n'; } void MetalDrawRoundShotStrategy::draw(const RoundShot& shot) { std::cout << "Metal Round Shot: " << shot.amount() << '\n'; } void MetalDrawGrapeShotStrategy::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(); }