Projet Fil Rouge V3 — Solutions

Projet Fil Rouge V3 — Solutions #

Classe Hero (étapes 8/9 — abstract + héritage) #

1242.2_Project_V3_FilRouge_Hero

Hero.h

#include <string>
#include <ostream>

namespace He_Arc::RPG
{
  class Hero
  {
  public:
    Hero() = default;
    Hero(int strength, int agility, int intelligence, double hp, std::string name);
    virtual ~Hero() = default;

    virtual void show() const;

    // Pure virtual: every concrete hero must define how it interacts.
    // A body is provided so subclasses can call Hero::interact() as a default greeting.
    virtual void interact(const Hero &other) = 0;

    std::string getName() const { return m_name; }
    int getStrength() const { return m_strength; }
    int getAgility() const { return m_agility; }
    int getIntelligence() const { return m_intelligence; }
    double getHp() const { return m_hp; }

    friend std::ostream &operator<<(std::ostream &s, const Hero &p);

  protected:
    int m_strength{0};
    int m_agility{0};
    int m_intelligence{0};
    double m_hp{0};
    std::string m_name{"no name"};
  };

  std::ostream &operator<<(std::ostream &s, const Hero &p);
}

Hero.cpp

namespace He_Arc::RPG
{
  Hero::Hero(int strength, int agility, int intelligence, double hp, std::string name)
    : m_strength(strength), m_agility(agility), m_intelligence(intelligence),
      m_hp(hp), m_name(name) {}

  void Hero::show() const
  {
    std::println("=================");
    std::println("HERO: {}", m_name);
    std::println("=================");
    std::println("strength:     {}", m_strength);
    std::println("agility:      {}", m_agility);
    std::println("intelligence: {}", m_intelligence);
    std::println("HP:           {}", m_hp);
  }

  // Default greeting — subclasses call this via Hero::interact(other)
  void Hero::interact(const Hero &other)
  {
    std::println("Hello valiant {}! I'm {}", other.getName(), m_name);
  }

  std::ostream &operator<<(std::ostream &s, const Hero &p)
  {
    std::print(s, "=================\nHERO: {}\n=================\n"
                  "strength:     {}\nagility:      {}\nintelligence: {}\nHP:           {}\n",
               p.getName(), p.getStrength(), p.getAgility(), p.getIntelligence(), p.getHp());
    return s;
  }
}

Classe Warrior (étape 8) #

1242.2_Project_V3_FilRouge_Warrior

Warrior.h

#include "Hero.h"

namespace He_Arc::RPG
{
  class Warrior : public Hero
  {
  public:
    Warrior(int strength = 10, int agility = 5, int intelligence = 1,
            double hp = 20, std::string name = "no_name_warrior")
        : Hero(strength, agility, intelligence, hp, name) {}

    ~Warrior() override = default;

    void interact(const Hero &other) override;
  };
}

Warrior.cpp

namespace He_Arc::RPG
{
  void Warrior::interact(const Hero &other)
  {
    std::println("I will fight you! @{}", other.getName());
  }
}

Classe Wizard (étape 8) #

1242.2_Project_V3_FilRouge_Wizard

Wizard.h

#include "Hero.h"

namespace He_Arc::RPG
{
  class Wizard : public Hero
  {
  public:
    Wizard(int strength = 2, int agility = 2, int intelligence = 10,
           double hp = 15, std::string name = "no_name_wizard", int mana = 10)
      : Hero(strength, agility, intelligence, hp, name), m_mana(mana) {}

    ~Wizard() override = default;

    void show() const override;
    void interact(const Hero &other) override;
    void castSpell(Hero &other);

  protected:
    int m_mana{0};
  };
}

Wizard.cpp

namespace He_Arc::RPG
{
  void Wizard::show() const
  {
    Hero::show();
    std::println("mana:         {}", m_mana);
  }

  void Wizard::interact(const Hero &other)
  {
    Hero::interact(other);
    std::println("Fellow traveler... I'm a bit lost, do you know where the Shire is?");
  }

  void Wizard::castSpell(Hero &other)
  {
    if (m_mana >= 2)
    {
      std::println("FIREBALL!! hahaha! (targeting {})", other.getName());
      m_mana -= 2;
    }
    else
    {
      std::println("Not enough mana!! Run?");
    }
  }
}

Classe Necromancer (étape 8) #

1242.2_Project_V3_FilRouge_Necromancer

Necromancer.h

#include "Wizard.h"

namespace He_Arc::RPG
{
  class Necromancer : public Wizard
  {
  public:
    Necromancer(int strength = 10, int agility = 5, int intelligence = 8,
                double hp = 20, std::string name = "no_name_necromancer", int mana = 10)
        : Wizard(strength, agility, intelligence, hp, name, mana) {}

    ~Necromancer() override = default;

    // Rising undead costs 2 mana
    void riseUndeads();
  };
}

Necromancer.cpp

namespace He_Arc::RPG
{
  void Necromancer::riseUndeads()
  {
    if (m_mana >= 2)
    {
      std::println("Creating undead... work in progress");
      m_mana -= 2;
    }
    else
    {
      std::println("Not enough mana!!");
    }
  }
}

Classe Sword (mise à jour) #

1242.2_Project_V3_FilRouge_Sword

Sword.h

namespace He_Arc::RPG
{
  class Sword
  {
  public:
    Sword() = default;
    explicit Sword(int damage) : m_damage(damage) {}
    virtual ~Sword() = default;

    int getDamage() const { return m_damage; }

  private:
    int m_damage{10};
  };
}

Programme principal (étapes 8/9) #

1242.2_Project_V3_FilRouge_main

main.cpp

#include <print>

#include "Warrior.h"
#include "Wizard.h"
#include "Necromancer.h"

int main()
{
  He_Arc::RPG::Warrior gimli{10, 5, 1, 20, "Gimli"};
  He_Arc::RPG::Wizard gandalf{2, 2, 10, 10, "Gandalf", 10};
  He_Arc::RPG::Necromancer sauron{20, 20, 10, 999.9, "Sauron", 50};

  gimli.show();
  std::println("");
  gandalf.show();
  std::println("");
  sauron.show();
  std::println("");

  gimli.interact(gandalf);
  std::println("");
  gandalf.interact(sauron);
  std::println("");
  sauron.interact(gimli);
  std::println("");

  sauron.castSpell(gandalf);
  sauron.riseUndeads();
  std::println("");

  sauron.show();

  return 0;
}