factoryMethod

 avatar
unknown
ruby
3 years ago
4.1 kB
0
Indexable
#include <iostream>
#include <unordered_map>

using namespace std;

enum class Class {
    Barbarian,
    Magician
};

enum class PrimaryWeapon {
    Sword, 
    Axe,
    Bow,
    MagicBook
};

enum class SecondaryWeapon {
    ShortSword,
    Shield,
    Arrows,
    None
};

enum class Tools {
    Lockpick,
    Bandages,
    Adrenaline, 
    ManaPotion
};

// unordered_map<PrimaryWeapon, string> primaryWeaponMap {
//     {PrimaryWeapon::Sword, "Sword"}
// };

struct StartingEquipment {
    PrimaryWeapon primaryWeapon;
    SecondaryWeapon secondaryWeapon;
    Tools tools;
};

class HeroClass {
  public:
    virtual void create() = 0;
    
    void setStrength(int a_strength) { strength = a_strength; }
    int getStrength() const { return strength; }
    
    void setDefence(int a_defence) { defence = a_defence; }
    int getDefence() const { return defence; }
    
    void setSpeed(int a_speed) { speed = a_speed; }
    int getSpeed() const { return speed; }
    
    void setIntelligence(int a_intelligence) { intelligence = a_intelligence; }
    int getIntelligence() const { return intelligence; }
    
    void setStartingEquipment(StartingEquipment a_startingEquipment) { startingEquipment = a_startingEquipment; } 
    StartingEquipment getStartingEquipment() const { return startingEquipment; };
  private:
    int strength;
    int defence;
    int speed;
    int intelligence;
    StartingEquipment startingEquipment;
};

class Barbarian : public HeroClass {
  public:
    void create() {
        setStrength(10);
        setDefence(5);
        setSpeed(3);
        setIntelligence(1);
        setStartingEquipment(StartingEquipment{ PrimaryWeapon::Axe, SecondaryWeapon::None, Tools::ManaPotion });
    }
};

class Magician : public HeroClass {
  public:
    void create() {
        setStrength(1);
        setDefence(3);
        setSpeed(5);
        setIntelligence(10);
        setStartingEquipment(StartingEquipment{ PrimaryWeapon::MagicBook, SecondaryWeapon::None, Tools::Bandages });
    }
};

class Character {
  public:
    virtual HeroClass* chooseClass() = 0;
    
    void create() { 
        heroClass = chooseClass(); 
        heroClass->create();
        printStats();
    }
    void levelUp() {
        heroClass->setStrength(heroClass->getStrength() + 1);
        heroClass->setDefence(heroClass->getDefence() + 1);
        heroClass->setSpeed(heroClass->getSpeed() + 2);
        heroClass->setIntelligence(heroClass->getIntelligence() + 3);
    }
    
    void printStats() {
        cout << "Strength: " << heroClass->getStrength();
        cout << "\nDefence: " << heroClass->getDefence();
        cout << "\nSpeed: " << heroClass->getSpeed();
        cout << "\nIntelligence: " << heroClass->getIntelligence();
        cout << "\n----------------------";
        cout << "\nStarting equipment:";
        // cout << "\nPrimary weapon: " << startingEquipment.primaryWeapon;
        // cout << "\nSecondary weapon: " << startingEquipment.secondaryWeapon;
        // cout << "\nTools: " << startingEquipment.tools;
        cout << "\n";
    }
  private:
    HeroClass* heroClass;
    int experience;
    int level;
};

class BarbarianCharacter : public Character {
  public:
    HeroClass* chooseClass() {
        return new Barbarian();
    }
};

class MagicianCharacter : public Character {
  public:
    HeroClass* chooseClass() {
        return new Magician();
    }
};

class CharacterCreator {
  public:
    Character* chooseClass(Class characterClass) {
        if(characterClass == Class::Magician) {
            return new MagicianCharacter();
        } else if(characterClass == Class::Barbarian) {
            return new BarbarianCharacter();
        } else {
            return nullptr;
        }
    }
    Character* create(Class characterClass) {
        character = chooseClass(characterClass);
        character->create();
        return character;
    }
  private:
    Character* character;
};

int main()
{
    CharacterCreator creator;
    Character* character = creator.create(Class::Magician);
    character->levelUp();
    character->printStats();
    
    return 0;
}