173 lines
4.6 KiB
C++
173 lines
4.6 KiB
C++
#include <algorithm>
|
|
#include <cassert>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <memory>
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
struct Time {};
|
|
template <typename T, typename U>
|
|
struct DifficultStrategy {};
|
|
struct PrintVisitor {};
|
|
|
|
class Ship {
|
|
public:
|
|
void setCrew(int crew) { _crew = crew; }
|
|
void setArmor(int armor) { _armor = armor; }
|
|
void setCannons(int cannons) { _canons = cannons; }
|
|
void setDurability(int durability) { _durability = durability; }
|
|
|
|
const std::string& name() const { return _name; }
|
|
int capacity() const { return _capacity; }
|
|
int crew() const { return _crew; }
|
|
int armor() const { return _armor; }
|
|
int canons() const { return _canons; }
|
|
int durability() const { return _durability; }
|
|
|
|
private:
|
|
// Allow to be created only by std::unique_ptr
|
|
friend std::unique_ptr<Ship> std::make_unique<Ship>();
|
|
friend class ShipBuilder;
|
|
Ship() = default;
|
|
|
|
Time* _time{};
|
|
std::unique_ptr<DifficultStrategy<Ship, bool>> _strategy{};
|
|
std::string _name{};
|
|
int _capacity{-1};
|
|
int _maxCrew{-1};
|
|
int _crew{10};
|
|
std::unique_ptr<PrintVisitor> _visitor{};
|
|
int _armor{0};
|
|
int _maxArmor{-1};
|
|
int _canons{0};
|
|
int _maxCannons{-1};
|
|
int _durability{100};
|
|
int _maxDurability{-1};
|
|
};
|
|
|
|
class ShipBuilder {
|
|
public:
|
|
ShipBuilder()
|
|
: _ship(std::make_unique<Ship>()) {}
|
|
|
|
[[nodiscard]] std::unique_ptr<Ship> build() {
|
|
if (!_ship) {
|
|
std::cout << "Builder may be use once\n";
|
|
return nullptr;
|
|
}
|
|
|
|
// Check mandatory fields
|
|
if (!_ship->_time ||
|
|
_ship->_name.empty() ||
|
|
_ship->_capacity == -1 ||
|
|
_ship->_maxCrew == -1 ||
|
|
_ship->_maxArmor == -1 ||
|
|
_ship->_maxCannons == -1 ||
|
|
_ship->_maxDurability == -1) {
|
|
std::cout << "Mandatory fields are not set!\n";
|
|
return nullptr;
|
|
}
|
|
|
|
return std::move(_ship);
|
|
}
|
|
|
|
ShipBuilder& setTime(Time* time) {
|
|
_ship->_time = time;
|
|
return *this;
|
|
}
|
|
ShipBuilder& setStrategy(std::unique_ptr<DifficultStrategy<Ship, bool>> strategy) {
|
|
_ship->_strategy = std::move(strategy);
|
|
return *this;
|
|
}
|
|
ShipBuilder& setName(const std::string& name) {
|
|
_ship->_name = name;
|
|
return *this;
|
|
}
|
|
ShipBuilder& setCapacity(int capacity) {
|
|
_ship->_capacity = capacity;
|
|
return *this;
|
|
}
|
|
ShipBuilder& setMaxCrew(int maxCrew) {
|
|
_ship->_maxCrew = maxCrew;
|
|
return *this;
|
|
}
|
|
ShipBuilder& setCrew(int crew) {
|
|
_ship->_crew = crew;
|
|
return *this;
|
|
}
|
|
ShipBuilder& setVisitor(std::unique_ptr<PrintVisitor> visitor) {
|
|
_ship->_visitor = std::move(visitor);
|
|
return *this;
|
|
}
|
|
ShipBuilder& setArmor(int armor) {
|
|
_ship->_armor = armor;
|
|
return *this;
|
|
}
|
|
ShipBuilder& setMaxArmor(int maxArmor) {
|
|
_ship->_maxArmor = maxArmor;
|
|
return *this;
|
|
}
|
|
ShipBuilder& setCannons(int cannons) {
|
|
_ship->_canons = cannons;
|
|
return *this;
|
|
}
|
|
ShipBuilder& setMaxCannons(int maxCannons) {
|
|
_ship->_maxCannons = maxCannons;
|
|
return *this;
|
|
}
|
|
ShipBuilder& setDurability(int durability) {
|
|
_ship->_durability = durability;
|
|
return *this;
|
|
}
|
|
ShipBuilder& setMaxDurability(int maxDurability) {
|
|
_ship->_maxDurability = maxDurability;
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<Ship> _ship;
|
|
};
|
|
|
|
class ShipJsonBuilder : private ShipBuilder {
|
|
public:
|
|
std::unique_ptr<Ship> buildBrig(Time* time, const std::string& name) {
|
|
return setTime(time)
|
|
.setName(name)
|
|
.setCapacity(500)
|
|
.setMaxCrew(200)
|
|
.setMaxArmor(1000)
|
|
.setMaxCannons(20)
|
|
.setMaxDurability(1000)
|
|
.build();
|
|
}
|
|
std::unique_ptr<Ship> buildFrigate();
|
|
std::unique_ptr<Ship> buildGaleon();
|
|
};
|
|
|
|
int main() {
|
|
auto ship = ShipBuilder().build();
|
|
if (ship) {
|
|
std::cout << "Ship name: " << ship->name() << '\n';
|
|
}
|
|
|
|
Time time;
|
|
auto ship2 = ShipBuilder()
|
|
.setTime(&time)
|
|
.setName("Black Pearl")
|
|
.setCapacity(500)
|
|
.setMaxCrew(200)
|
|
.setMaxArmor(1000)
|
|
.setMaxCannons(20)
|
|
.setMaxDurability(1000)
|
|
.build();
|
|
|
|
if (ship2) {
|
|
std::cout << "Ship name: " << ship2->name() << '\n';
|
|
}
|
|
|
|
auto ship3 = ShipJsonBuilder().buildBrig(&time, "Black Widow");
|
|
if (ship3) {
|
|
std::cout << "Ship name: " << ship3->name() << '\n';
|
|
}
|
|
}
|