设计一个简单的面向对象游戏类层次结构

4

我正在尝试制作一款战舰游戏(参见维基百科:战舰游戏)。

我有一个Player类、一个Grid类和一个Ship类。

每个玩家都有一个网格,每个网格上都有一组战舰。

如何确定在玩家类还是网格类中设置舰船集合?

在游戏开始时,玩家必须将他们的舰船放置在网格上。我有一个方法来询问玩家在哪里放置他们的舰船。如何确定该方法应放在哪个类中?如果它在玩家类中,但是舰船集合在网格类中,那么我就必须从网格中获取舰船集合的引用。然后,我应该使用Grid::PlaceShip(Ship)还是Ship::Place(x,y)?

是否有一种方法论可以解决这个问题?我已经尝试了“类-责任-协作”(CRC)方法,但它并没有给我提供答案让我开始编码。我宁愿学会如何自己找到答案,而不是为这个特定的例子提供答案。


你是否错过了Game概念?行为几乎从不发生在代表所有行为发起者的实体上,比如PlayerUser等。否则,所有行为将在这些实体上进行。也许game.placeInitialShipsFor(player, shipLocations) - plalx
我有一个Game类,我试图简化我认为涉及的类。我可能会把所有东西都添加到Game类中,但我读过这是一个错误。游戏启动行为,玩家负责放置船只,船只负责被放置,这取决于你如何思考,这让我感到困惑。 - Qgenerator
谁负责维护数据的完整性?例如,只有游戏知道轮到哪个玩家和谁已经进行了初始放置。如果高级别函数放置在“Game”对象上,则类似于“Grid”和“Player”的类仍将参与其中。 - plalx
在我的看法中,“船只对于被放置负责”这个概念并不是很有意义。在战舰游戏中,我期望船只知道它们的总体/剩余血量,而不会知道太多其他信息。总的来说,这是一个相当主观的问题,对于“如何为X设计类”这个一般性问题,没有单一的方法论可以作为充分的答案。 - Preston Guillot
每个玩家都有自己的网格,在游戏中放置初始船只,如果没有参考网格,似乎会让人感到非常困惑。 - Qgenerator
1个回答

2

这取决于周围的代码,但我的直觉是Ship应该是Grid的一部分。Grid和Ship所代表的信息有很多重叠,而这些信息并不真正涉及到玩家:特定的网格位置、合法的猜测等等。如果你将Ship作为Player的一部分,仍然需要直接链接两者,以便Grid知道船是否被击中。如果Grid甚至不知道船在哪里,那么它就没有意义了。

关于如何构建对象模型,没有真正的硬性答案。我试图想象我可能需要编写的函数/方法/子程序,而不管对象模型如何。如果相同的概念在同一组函数中开始出现,那么它们应该在对象模型中绑定在一起。

还要注意,在代码的不同部分中多次表示相同的信息。对于每个任务或资源,请确保只有代码的一个部分负责它。您可能需要调整抽象层次结构,以使负责的代码可以用于略微不同但都涉及相同类型工作的事情。

您的目标是简单的代码。如果您开始编写代码,随着编写的过程变得更加复杂(即更难理解),那么这表明您需要重新思考和重构您的模型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接