Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
文本冒险游戏-如何区分一种物品类型和另一种,以及如何构造物品类/子类? 我是一个初学者程序员(他有一系列与设计相关的脚本经验,但是很少有编程经验——所以只需要基本的东西,比如循环、流控制等等),虽然我有一个C++基础和C++的数据结构和算法的课程。我正在做一个文本冒险的个人项目(其实我早在很久以前就已经用Python写过了,在我学会类的工作原理之前——一切都是一本字典——所以这是可耻的)。我在用C++来“重做”它,让我们摆脱只做作业的习惯。_C++_Game Development_Adventure - Fatal编程技术网

文本冒险游戏-如何区分一种物品类型和另一种,以及如何构造物品类/子类? 我是一个初学者程序员(他有一系列与设计相关的脚本经验,但是很少有编程经验——所以只需要基本的东西,比如循环、流控制等等),虽然我有一个C++基础和C++的数据结构和算法的课程。我正在做一个文本冒险的个人项目(其实我早在很久以前就已经用Python写过了,在我学会类的工作原理之前——一切都是一本字典——所以这是可耻的)。我在用C++来“重做”它,让我们摆脱只做作业的习惯。

文本冒险游戏-如何区分一种物品类型和另一种,以及如何构造物品类/子类? 我是一个初学者程序员(他有一系列与设计相关的脚本经验,但是很少有编程经验——所以只需要基本的东西,比如循环、流控制等等),虽然我有一个C++基础和C++的数据结构和算法的课程。我正在做一个文本冒险的个人项目(其实我早在很久以前就已经用Python写过了,在我学会类的工作原理之前——一切都是一本字典——所以这是可耻的)。我在用C++来“重做”它,让我们摆脱只做作业的习惯。,c++,game-development,adventure,C++,Game Development,Adventure,我已经编写了我的player和room类(很简单,因为每个类只需要一个类)。我进入了物品类(物品是房间里的任何东西,如手电筒、火、标志、容器等)。我不确定如何接近项基类和派生类。以下是我遇到的问题 我如何以一种非狗屎的方式判断一件物品是否属于某种类型(我很有可能是想得太多了) 例如,我设置了“打印室信息”功能,以便它除了可以执行其他操作外,还可以打印其库存中每个对象的名称(即库存内部),并且我希望它打印容器对象的特殊内容(例如库存内容) 第一部分很简单,因为每个项都有一个名称,因为name属性

我已经编写了我的player和room类(很简单,因为每个类只需要一个类)。我进入了物品类(物品是房间里的任何东西,如手电筒、火、标志、容器等)。我不确定如何接近项基类和派生类。以下是我遇到的问题

  • 我如何以一种非狗屎的方式判断一件物品是否属于某种类型(我很有可能是想得太多了)

    • 例如,我设置了“打印室信息”功能,以便它除了可以执行其他操作外,还可以打印其库存中每个对象的名称(即库存内部),并且我希望它打印容器对象的特殊内容(例如库存内容)
    • 第一部分很简单,因为每个项都有一个名称,因为name属性是基本项类的一部分。不过,容器有一个清单,这是容器子类特有的属性
    • 我的理解是,基于对象的类类型执行条件逻辑是不好的(因为一个人的类应该是多态的),我假设(可能是错误的)将getHasInventory访问器虚拟函数放在item基类中是奇怪和错误的(我在这里的假设是基于这样的想法:将每个派生类的虚拟函数都放在基类中是疯狂的——我有十几个派生类——其中有两个是派生类的派生类)
    • 如果这些都是正确的,那么什么是可以接受的方法呢?一个显而易见的方法是向基添加itemType属性,然后执行条件逻辑,但这让我觉得是错误的,因为这似乎只是检查类类型解决方案的重新蒙皮。我不确定上述假设是否正确,以及什么是好的解决方案可能是
  • 我应该如何构造我的基类和派生类

    • 我最初编写它们是为了让item类成为基类,而大多数其他类使用单一继承(除了一对具有多级继承的类)
    • 这似乎有点尴尬,重复了我自己。例如,我想要一个符号和一个字母。符号是可读项>不可提取项>项。字母是可读项>可提取项>项。因为它们都使用单一继承,我需要两个不同的可读项,一个可提取,一个不可提取(我知道在本例中我可以将takeable和untakeable设置为base的属性,我确实这样做了,但这只是一个例子,因为我在其他类中仍然存在类似的问题)
    • 这对我来说似乎很棘手,所以我又尝试了一次,并使用多重继承&虚拟继承来实现它们。在我的例子中,这似乎更灵活,因为我可以组合多个类的类,并为我的类创建一种组件系统
    • 这些方法中有一种比另一种好吗?有第三种方法更好吗

  • 解决问题的一种可能方法是多态性。通过使用多态性,您可以(例如)拥有一个
    descripe
    函数,当调用该函数时,该函数将引导项目向玩家描述自身。您可以对
    use
    和其他常用动词执行相同的操作


    另一种方法是实现更高级的输入解析器,该解析器可以识别对象并将谓词传递给项目的某些(多态)函数供其自己处理。例如,每个项目都可以有一个函数返回可用谓词的列表,还有一个函数返回项目的“名称”列表:

    struct item
    {
        // Return a list of verbs this item reacts to
        virtual std::vector<std::string> get_verbs() = 0;
    
        // Return a list of name aliases for this item
        virtual std::vector<std::string> get_names() = 0;
    
        // Describe this items to the player
        virtual void describe(player*) = 0;
    
        // Perform a specific verb, input is the full input line
        virtual void perform_verb(std::string verb, std::string input) = 0;
    };
    
    class base_torch : public item
    {
    public:
        std::vector<std::string> get_verbs() override
        {
            return { "light", "extinguish" };
        }
    
        // Return true if the torch is lit, false otherwise
        bool is_lit();
    
        void perform_verb(std::string verb, std::string) override
        {
            if (verb == "light")
            {
                // TODO: Make the torch "lit"
            }
            else
            {
                // TODO: Make the torch "extinguished"
            }
        }
    };
    
    class long_brown_torch : public base_torch
    {
        std::vector<std::string> get_names() override
        {
            return { "long brown torch", "long torch", "brown torch", "torch" };
        }
    
        void describe(player* p) override
        {
            p->write("This is a long brown torch.");
            if (is_lit())
                p->write("The torch is burning.");
        }
    };
    
    struct项
    {
    //返回此项响应的谓词列表
    虚拟std::vector get_动词()=0;
    //返回此项的名称别名列表
    虚拟std::vector get_names()=0;
    //向玩家描述这些物品
    虚拟空描述(玩家*)=0;
    //执行特定动词,输入是完整的输入行
    虚拟void执行动词(std::string动词,std::string输入)=0;
    };
    基本类火炬:公共物品
    {
    公众:
    std::vector get_动词()覆盖
    {
    返回{“灯”,“熄灭”};
    }
    //如果火炬点亮,则返回true,否则返回false
    bool是_lit();
    void执行动词(std::string动词,std::string)重写
    {
    如果(动词==“轻”)
    {
    //TODO:使火炬“点燃”
    }
    其他的
    {
    //TODO:使火炬“熄灭”
    }
    }
    };
    班长\棕色\火炬:公共基地\火炬
    {
    std::vector get_names()覆盖
    {
    返回{“长棕色火炬”、“长火炬”、“棕色火炬”、“火炬”};
    }
    无效描述(玩家*p)覆盖
    {
    p->写(“这是一个长长的棕色火炬。”);
    如果(是_lit())
    p->写(“火炬在燃烧”);
    }
    };
    
    然后,如果玩家输入,例如
    浅棕色手电筒
    解析器检查所有可用项目(玩家清单中的项目,然后是房间中的项目),获取每个项目名称列表(调用项目
    get_names()
    函数)并将其与
    brown torch
    进行比较。如果找到匹配项,解析器将调用items
    perform\u verb
    函数传递适当的参数(
    item-