C++ C++;确定类是否可以使用对象文本RPG游戏

C++ C++;确定类是否可以使用对象文本RPG游戏,c++,inheritance,C++,Inheritance,我面临以下设计问题: TL;TD需要确定Hero(类)是否可以使用特定的对象,同时还有许多Hero实现 我有3个子类的类英雄,每一个都可以使用特定的项目 我有剑,锤子,弩,弓,魔杖,棍子 战士可以使用剑或锤 弓箭手可以使用弩或弓 向导可以使用棍棒或魔杖 有一个英雄基类: class Hero: public Entity{ public: Hero(std::string name, Gender gender, double damage, Point2d* location);

我面临以下设计问题:

TL;TD需要确定Hero(类)是否可以使用特定的对象,同时还有许多Hero实现

我有3个子类的类英雄,每一个都可以使用特定的项目

我有剑,锤子,弩,弓,魔杖,棍子

战士可以使用剑或锤 弓箭手可以使用弩或弓 向导可以使用棍棒或魔杖

有一个英雄基类:

class Hero: public Entity{

public:
    Hero(std::string name, Gender gender, double damage, Point2d* location);
    ~Hero();
    virtual void move(int x, int y);
    virtual void damage(Entity* other); // Override
    virtual bool use(Potion* _potion);
    virtual bool use(Weapon* _weapon) = 0;
    virtual bool use(ShieldArmor* _shieldArmor) = 0;
    virtual bool use(BodyArmor* _bodyArmor) = 0;

private:
    std::string name;
    Gender gender;
    Weapon* weapon;
    ShieldArmor* shield_armor;
    BodyArmor* body_armor;
};
这就是武器:

class Weapon: public Item{

public:
    Weapon(double damage, Point2d* location); 
    virtual ~Weapon();
    virtual double getDamage() const;
    virtual const Point2d* getLocation() const; 
    virtual const std::string toString() const;

private:
    Point2d* location;
    double damage; 
};
在游戏中,如果可能的话,我需要确定英雄*h是否可以使用特定的物品而无需向下施法

所以我可以像这样使用它:

Hero *h;
Weapon * i;
// do something assign values
h->use(i);

您可以使用
dynamic_cast()
确定英雄指针的类型,如下所示:

Hero *h;
Weapon * i;
// do something assign values
if(dynamic_cast<HeroSubClass> != nullptr)
    h->use(i);
Hero*h;
武器*i;
//做点什么来赋值
if(动态_cast!=nullptr)
h->使用(i);
其中,
herosublass
是要检查的
Hero
的特定子类(
Warrior
,等等)。如果您的
Hero*
不是指向类
herosublass
的对象的指针,
dynamic\u cast
将返回
nullptr
,如果是,它将返回
herosublass*


或者,你可以在
use()
中为每个hero子类检查
武器*
的类型,如果它是一个错误类的对象,也许可以打印出类似“Warrior can use Staff”的内容。

你可以使用
enum
值来定义武器和英雄的特定类型

enum class HERO_TYPE{
   WARRIOR,
   ARCHER,
   WIZARD
}

class Hero: public Entity{

public:
    Hero( std::string name, Gender gender, double damage, Point2d* location, HERO_TYPE type );
    ~Hero();
    virtual void move(int x, int y);
    virtual void damage(Entity* other); // Override
    virtual bool use(Potion* _potion);
    virtual bool use(Weapon* _weapon) = 0;
    virtual bool use(ShieldArmor* _shieldArmor) = 0;
    virtual bool use(BodyArmor* _bodyArmor) = 0;

private:
    std::string name;
    Gender gender;
    Weapon* weapon;
    ShieldArmor* shield_armor;
    BodyArmor* body_armor;
    HERO_TYPE type; //define in subclasses.
};
武器也是如此

enum class WEAPON_TYPE{
       SWORD,
       CROSSBOW,
       WAND
    }
class Weapon: public Item{

public:
    Weapon(double damage, Point2d* location, WEAPON_TYPE type); 
    virtual ~Weapon();
    virtual double getDamage() const;
    virtual const Point2d* getLocation() const; 
    virtual const std::string toString() const;
    WEAPON_TYPE get_type() { return this->type; }//getter

private:
    Point2d* location;
    double damage;
    WEAPON_TYPE type;
};
现在你可以为英雄职业指定武器了

void Hero::use(Weapon *i){
   if(!checkWeapon(i->get_type())) return;

  //...code...

}

bool Hero::checkWeapon(WEAPON_TYPE t){
  switch(this->type){
     case HERO_TYPE::WARRIOR:{
        if(t == WEAPON_TYPE::SWORD)
            return true;
     }break;

     case HERO_TYPE::ARCHER:{
        if(t == WEAPON_TYPE::CROSSBOW)
            return true;
     }break;

     //..all cases..
  }

  return false;//no hero-weapon matching
}

我正在考虑使用访问者模式

比如:

Hero * h;
Item * i;
Visitor v;
// Assign some values
h.accept(v,i);
然后访客看起来像:

visit(sword *p, warrior * w){
    w.use(p);
}
visit(wand *p, wizard * w){
    w.use(p);
}
visit(bow *p, archer * w){
    w.use(p);
}

对这个想法有什么建议吗

我简化了示例,删除了所有不必要的内容,并将其概括为
的概念。武器是物品的一个子类,药剂、魔杖、通量电容器等等都是。
use
方法执行
项对
目标所做的任何操作。武器将试图击中并伤害
目标
。治疗药剂将治疗目标。磁通电容器要么将
target
发送回时间,要么以1.21千兆瓦的功率将删除的咒语从中消除

但一切都是通过
项目的镜头来看待的。调用类不知道该项是什么,做了什么,或者它对
目标做了什么<代码>目标
甚至不知道它使用了什么,他们只是感觉到了效果。除了简单的通用接口之外,没有人对其他对象一无所知

class Item
{
public:
    enum types
    {
        whole lot of types go here.
        They are fairly broad categories, like knife, sword, two handed sword, 
        healing potion, wand, etc.
    };
    types getType()
    {
         return type;
    }
    virtual bool use(Entity * target) = 0;
private:
    types type;

};

class Hero: public Entity{

public:
    Hero(std::set<Item::type> & usable): usableItems(usable)
    ~Hero();
    bool use(Item* item,
             Entity * target)
    {
        // this is the magic. If the item's type is in the list of usable items,
        // the item is used on the target. They exact type of item or target
        // is not known. Polymorphism will take care of everything from here
        if (usableItems.find(item->getType()) != usableItems.end())
        {
            return item->use(target);
        }
        return false;
    }
private:
    std::set<Item::type> & usableItems;
};
类项目
{
公众:
枚举类型的
{
这里有很多种类。
它们是相当广泛的类别,像刀,剑,双手剑,
治疗药剂、魔杖等。
};
类型getType()
{
返回类型;
}
虚拟布尔使用(实体*目标)=0;
私人:
类型;
};
类英雄:公共实体{
公众:
英雄(标准::设置和可用):可用项(可用)
~Hero();
bool用途(项目*项目,
实体*目标)
{
//这就是魔法。如果物品的类型在可用物品列表中,
//该项目用于目标。它们与项目或目标的类型完全相同
//不知道。多态性将从这里处理一切
if(usableItems.find(item->getType())!=usableItems.end())
{
退货项目->使用(目标);
}
返回false;
}
私人:
标准:设置和使用的项目;
};
关键是,主要的班级都非常愚蠢。它们只是为更详细的对象提供了一个框架来完成详细的工作
VorpalSword
使用从
武器
物品
继承的通用方法来查看它是否击中
目标
,而不知道
目标
实际上是一个
巨大的DDRAGON
实例,如果它击中了指定的伤害,然后做了一个
word
所做的特定事情,比如检查断肢


英雄看到的只是
item->use(target)

有趣的事实:你不需要对所有事情都使用指针。最好避免使用指针,而使用静态分配、容器和引用。@user4581301映射的输入是动态的。在从地图输入中获得英雄类型后,我需要根据一些输入来确定所有这些。在不知道武器使用规则的情况下,很难说解决问题的最佳方法。以老派D&D为例,你可以让
类包含一个
std::set AllowedWearms
,列出所有允许的武器类型和一个
bool canUse(武器*)
方法,如果武器类型在
集中,该方法返回true<代码>类武器
需要一个
weapontype getType()
方法来支持它。所以
职业教士:公共职业
会在攻击前初始化
允许的武器({one handbunt,two handbunt,…})
英雄
我的职业->可以使用(武器)
。强制代码知道
英雄
和武器是什么,让你重新开始施放。可行,但不是特别好的解决方案。