198 lines
No EOL
6 KiB
C++
198 lines
No EOL
6 KiB
C++
#include <algorithm>
|
|
#include <cassert>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <memory>
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
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 <typename T>
|
|
class FireStrategy {
|
|
public:
|
|
virtual void fire(const T& shot) = 0;
|
|
};
|
|
|
|
class SDLFireRoundShotStrategy : public FireStrategy<RoundShot> {
|
|
public:
|
|
void fire(const RoundShot& shot) override;
|
|
};
|
|
|
|
class SDLFireChainShotStrategy : public FireStrategy<ChainShot> {
|
|
public:
|
|
void fire(const ChainShot& shot) override;
|
|
};
|
|
|
|
class SDLFireGrapeShotStrategy : public FireStrategy<GrapeShot> {
|
|
public:
|
|
void fire(const GrapeShot& shot) override;
|
|
};
|
|
|
|
class WAMFireRoundShotStrategy : public FireStrategy<RoundShot> {
|
|
public:
|
|
void fire(const RoundShot& shot) override;
|
|
};
|
|
|
|
class WAMFirChainShotStrategy : public FireStrategy<ChainShot> {
|
|
public:
|
|
void fire(const ChainShot& shot) override;
|
|
};
|
|
|
|
class WAMFireGrapeShotStrategy : public FireStrategy<GrapeShot> {
|
|
public:
|
|
void fire(const GrapeShot& shot) override;
|
|
};
|
|
|
|
template <typename T>
|
|
class DrawStrategy {
|
|
public:
|
|
virtual void draw(const T& shot) = 0;
|
|
};
|
|
|
|
class OpenGLDrawRoundShotStrategy : public DrawStrategy<RoundShot> {
|
|
public:
|
|
void draw(const RoundShot& shot) override;
|
|
};
|
|
|
|
class OpenGLDrawChainShotStrategy : public DrawStrategy<ChainShot> {
|
|
public:
|
|
void draw(const ChainShot& shot) override;
|
|
};
|
|
|
|
class OpenGLDrawGrapeShotStrategy : public DrawStrategy<GrapeShot> {
|
|
public:
|
|
void draw(const GrapeShot& shot) override;
|
|
};
|
|
|
|
class MetalDrawRoundShotStrategy : public DrawStrategy<RoundShot> {
|
|
public:
|
|
void draw(const RoundShot& shot) override;
|
|
};
|
|
|
|
class MetalDrawChainShotStrategy : public DrawStrategy<ChainShot> {
|
|
public:
|
|
void draw(const ChainShot& shot) override;
|
|
};
|
|
|
|
class MetalDrawGrapeShotStrategy : public DrawStrategy<GrapeShot> {
|
|
public:
|
|
void draw(const GrapeShot& shot) override;
|
|
};
|
|
|
|
class RoundShot : public Ammunition {
|
|
public:
|
|
RoundShot(size_t amount, std::unique_ptr<FireStrategy<RoundShot>>&& fireStrategy, std::unique_ptr<DrawStrategy<RoundShot>>&& 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<RoundShot>> _fireStrategy;
|
|
std::unique_ptr<DrawStrategy<RoundShot>> _drawStrategy;
|
|
};
|
|
|
|
class ChainShot : public Ammunition {
|
|
public:
|
|
ChainShot(size_t amount, std::unique_ptr<FireStrategy<ChainShot>>&& fireStrategy, std::unique_ptr<DrawStrategy<ChainShot>>&& 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<ChainShot>> _fireStrategy;
|
|
std::unique_ptr<DrawStrategy<ChainShot>> _drawStrategy;
|
|
};
|
|
|
|
class GrapeShot : public Ammunition {
|
|
public:
|
|
GrapeShot(size_t amount, std::unique_ptr<FireStrategy<GrapeShot>>&& fireStrategy, std::unique_ptr<DrawStrategy<GrapeShot>>&& 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<GrapeShot>> _fireStrategy;
|
|
std::unique_ptr<DrawStrategy<GrapeShot>> _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<Ammunition> grapeShot = std::make_unique<GrapeShot>(
|
|
100, std::make_unique<SDLFireGrapeShotStrategy>(), std::make_unique<OpenGLDrawGrapeShotStrategy>());
|
|
|
|
grapeShot->fire();
|
|
grapeShot->draw();
|
|
} |