问题描述
我正在尝试创建一个D&D遭遇模拟器。 因此,我创建了一个名为“演员”的类来模仿玩家和怪物的行为。问题在于,尽管目前该类别仅具有3个成员变量,但随着模拟变得更加准确,有必要添加更多的成员变量来最好地模拟怪物和玩家的数据,例如强度,灵活性等(可能超过10个成员变量) 这导致构造函数具有很多参数,因此问题就变成了;有没有更好的方法来组织这些数据,因为所有数据都可以随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力量之戒”或被诸如Polymorph之类的咒语击中。
,这是C ++中多态性的基本概念,我建议从阅读它开始
例如,您可以让基类Actor包含模拟器中每个实体(怪物,玩家等)拥有的基本信息。
然后,您可以创建一个从Actor类派生的Monster和Player类。这些将具有自己的独特信息(牙齿大小,水下呼吸,飞行等)。
如果要在仿真过程中为播放器动态创建新的统计信息,我建议使用智能指针来保存这些成员以进行内存优化。
,如果您不希望在actor的构造函数中为actor的每个属性都拥有一个参数,则可以考虑使用单独的stats对象,并将该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;
}
这样一来,您无需为每个统计信息实现getter / setter,也无需为初始化统计信息的函数使用friend
。但是原始值一经传递到Actor
,就仍然受到保护。
这导致构造函数具有很多参数,因此问题就变成了;有没有更好的方法来组织这些数据,因为所有数据都可以随actor类的每个实例而变化?
现在,用户需要手动输入所有状态,尽管我计划让以后读取怪物的文件,因为怪物统计信息仅随怪物类型(龙,骷髅等)而变化
听起来这个问题不是关于如何设计OOP的问题,而是关于如何定义程序的所有统计信息而又没有那么麻烦的问题。
从文件读取统计信息是一个好主意。您可以在一个或多个JSON文件中表示它们,并使用Nlohmann's JSON library将其读入程序。您仍然必须编写代码,说明您的程序应如何使用读取的JSON数据,当然,您首先需要编写JSON-不提供免费午餐。但是,它可能对组织程序很有帮助。
另一个想法:对于像兽人大军这样的演员,或者在存在多个相同种类的实例的地方,一种有用的方法是定义一个兽人factory function来创建兽人演员及其属性。工厂可以伪随机地改变速度,力量等,从而使每个兽人的个性化设置略有不同,而不必手动为每个实例编写统计信息。