C++ 成员众多的班级

C++ 成员众多的班级,c++,class,constructor,member,class-design,C++,Class,Constructor,Member,Class Design,我正在尝试创建一个D&D遭遇模拟器。 因此,我创建了一个名为“Actor”的类来模拟玩家和怪物的行为。问题是,虽然目前该类只有3个成员变量,但随着模拟变得更加精确,有必要添加更多成员变量,以最佳模拟怪物和玩家的统计数据,例如力量、灵巧度等(可能超过10个成员变量) 这导致了一个具有大量参数的构造函数,因此问题就变成了;有没有更好的方法来组织这些数据,因为它可以随actor类的每个实例而变化 现在,用户需要手动输入所有状态,尽管我计划以后可以读取怪物的文件,因为怪物的统计数据只会随着怪物类型(龙、

我正在尝试创建一个D&D遭遇模拟器。 因此,我创建了一个名为“Actor”的类来模拟玩家和怪物的行为。问题是,虽然目前该类只有3个成员变量,但随着模拟变得更加精确,有必要添加更多成员变量,以最佳模拟怪物和玩家的统计数据,例如力量、灵巧度等(可能超过10个成员变量) 这导致了一个具有大量参数的构造函数,因此问题就变成了;有没有更好的方法来组织这些数据,因为它可以随actor类的每个实例而变化

现在,用户需要手动输入所有状态,尽管我计划以后可以读取怪物的文件,因为怪物的统计数据只会随着怪物类型(龙、骷髅等)的不同而变化

注意:这些统计数据非常重要,用于计算“Actor”类在遭遇战中可以采取的每个动作的结果

编辑: 很多人建议使用继承,但事实是(怪物和玩家)从来没有不同的属性,像玩家这样的怪物由玩家(游戏大师)控制。这是一个桌面游戏,模拟器应该帮助游戏大师在真实游戏之前平衡遭遇

Actor.h

#ifndef actor_h_
#define actor_h_

#include "dice.h"

class Actor
{
  private:
    signed int hp;
    signed int ac; // Armor Class
    signed int dmg;
    
  public:
    Actor( signed int hp, int ac, int dmg);
    ~Actor();

    signed int getHP( void );
    signed int getAC( void );
    signed int getDmg( void );
    void setHP(signed int newHP);
    void setAC(signed int newAC);
    void setDmg(signed int newDmg);

    void attack(Actor* target);
};
#endif
参与者构造函数

Actor::Actor(signed int hp, signed int ac, signed int dmg)
{
  this->hp = hp;
  this->ac = ac;
  this->dmg = dmg;
}
Actor::~Actor(){}

当你自己举出统计数据的例子时,这些数据可能会在一段时间内消失

struct StatsBlock {
    int str, dex, con, /*others*/;
};
然后,您可以从静态类变量或静态方法中获取它们:

class Skeleton : public Actor {
...
public:
static inline const StatsBlock = { 13, 8, ... };
static StatsBlock rollStats() { ... );
};

作为奖励,这也给你提供了一个中心位置,用来暂时改变统计数据的效果,比如配备一个“+1强度的环”或被拼写成多个拼写的变体。

< P>这是C++中多态性的基本概念,我建议从阅读它的

开始。 例如,您可以让基类参与者包含模拟器中每个实体(怪物、玩家等)所拥有的基本信息

然后,您可以创建一个怪物和一个玩家类,它们派生自您的演员类。它们会有自己独特的信息(牙齿大小、水下呼吸、苍蝇等)


如果你想在模拟过程中动态地为你的玩家创建新的统计数据,我建议使用智能指针来保存这些成员进行内存优化。

< P>如果在演员的构造函数中不想为演员的属性的每个属性都有一个参数,可以考虑有一个单独的STATS对象,并将该统计数据的实例传递给构造器:

struct ActorStats {
    signed int hp;
    signed int ac; // Armor Class
    signed int dmg;
}

struct Actor {
  Actor(ActorStats stats) : stats_(std::move(stats)) {}

  signed int getHP( void );
  signed int getAC( void );
  signed int getDmg( void );
  void setHP(signed int newHP);
  void setAC(signed int newAC);
  void setDmg(signed int newDmg);

  void attack(Actor* target);

  protected:
    ActorStats stats_;
};
然后,您可以使用不同的创建参与者的策略,如从保存文件或预设中读取:

ActorStats read_stats_from_file() {
    ActorStats stats;
    // some reading logic

    stats.hp = // value read from file

    return stats;
}

Actor create_actor() {
    ActorStats stats = read_stats_from_file();
    Actor actor(stats);

    return Actor;
}
这样,您就不需要为每个stats实现getter/setter,也不需要为应该初始化stats的函数使用
friend
。但是原始值在传递给
参与者后仍然受到保护

这导致了一个具有大量参数的构造函数,因此问题就变成了;有没有更好的方法来组织这些数据,因为它可以随actor类的每个实例而变化?
现在,用户需要手动输入所有状态,尽管我计划以后可以读取怪物的文件,因为怪物的统计数据只会随着怪物类型(龙、骷髅等)的不同而变化

听起来,这个问题不是关于如何设计OOP,而是如何定义程序的所有统计信息,而不是让它变得非常麻烦

从文件中读取统计数据是一个好主意。您可以在一个或多个JSON文件中表示它们,并使用它将其读入程序。您仍然需要编写代码来说明您的程序应该如何使用读取的JSON数据,当然,您首先需要编写JSON——没有免费的午餐。不过,这可能有助于组织该计划


另一个想法是:对于兽人大军这样的演员,或者任何有多个同类实例的地方,一个有用的方法是定义一个兽人,创建一个兽人演员及其统计数据。工厂可以伪随机地改变速度、强度等,这样每个兽人的个性化程度就会有所不同,而不必手动为每个实例编写统计数据。

在我看来,Actor应该是一个虚拟类,“PC”、“NPC”和“怪物”类继承了它。。。因为不是所有人都需要相同的参数。你可能是对的,但问题是在D&D战斗中,怪物和PC使用相同的统计数据,因此它们需要相同的参数,NPC不是一个因素,因为它们在战斗中由PC控制,也使用相当于PC的统计数据。有一本书叫做iOS Swift Game Development Cookbook,讨论了处理这种情况的各种策略。信息是好的,即使您必须从平台和语言中提取它。(我知道,你可能不是在为iOS编程,而你不是在Swift编程。)也许有一个“游戏开发食谱”用于你的平台和C++。@ MortenKristensen,你所说的是一个“战斗者”,它拥有所有战斗状态-然后其他类型的。actor@UKMonkey这个游戏是桌面RPG(游戏不是在电脑上玩的),故事和NPC由游戏大师控制,在游戏中玩家可以在战斗中遇到敌人。唯一的目标是给游戏大师一个工具来模拟这些遭遇的结果,以确保遭遇不会太容易或太难。游戏的所有其他方面与sim无关这是一个好主意!太棒了。你认为使用你的例子是一个可行的想法,但给用户输入自定义统计数据的选项吗?例如,反映不同游戏的玩家可能会选择不同的统计数据分布,从而考虑玩家选择?如果