首页 > 解决方案 > 从另一个包含的类对象访问包含的类对象中的数据的“OOP 方式”是什么?

问题描述

出于教育目的,我正在尝试在 C# 控制台中创建纸牌游戏“大富翁交易”的副本。我的班级设计有一个问题,我不知道如何解决。我有两个班,GamePlayerGame控制游戏的状态,并包含一个Player对象列表。

目前它的工作方式是Game类控制一切。Player基本上是一个容器类:它包含玩家收藏中的所有卡片。决策由Game班级完成,因为它可以看到所有玩家,因此知道哪些动作是可能的。

例如,如果玩家 1 想从玩家 2 那里偷一张牌,我的程序必须首先验证玩家 2 是否有任何牌可以偷。玩家 1 不知道这一点,因为它只是对象列表中的一个Player对象。所以这个Game类有一个方法来检查玩家可以做出的所有可能的动作,要求玩家选择他们想要做出的动作,然后为他们执行那个动作。

我的问题:我认为这不是好的 OOP 类设计。我认为我应该将决策权委托给Player班级,而不是Game班级 - 否则我的Game班级将变得臃肿,有很多与玩家行为和决策相关的方法,而不是游戏状态本身。但是,我不知道如何实现这一点。

可能的解决方案:

  1. 创建一个GameState仅包含其他玩家卡牌的有限视图的对象,并将其传递给该Player对象(似乎是最简单的方法,但我猜它会创建冗余数据,这会浪费内存。)
  2. 将整个Game对象的引用传递给Player类(我可以这样做 - 这不像我要通过 ComputerPlayers 编程来作弊 - 但也感觉不是好的 OOP 设计)
  3. 放弃,把所有的游戏逻辑(包括计算机 AI)放在Game课堂上,并接受它Player只是一个数据容器,而不是决策者。
  4. 以不同的方式重新设计我的课程。
  5. 还有什么我错过的吗?

这里有什么明显的解决方案吗?谢谢你。


编辑:我试图减少问题中的过多细节,因为它因“没有足够的焦点”而关闭。如果需要进一步修改,请告诉我。

标签: c#classoopconsole-applicationclass-design

解决方案


如何创建一个代表您可以在游戏中执行的动作的动作类。然后游戏只有两个方法 Game.verifyAction(action) 和 Game.executeAction(action)。游戏包含验证和执行操作所需的所有数据。

接下来,将玩家视为数据容器,这意味着玩家不会认为它只是包含在状态中。玩家可能包含诸如分数、id 等数据。实际上认为您有一个负责选择动作的代理类。所以 Agent.think(Game) 返回代理在此状态下想要采取的动作。

现在很容易将主循环移到 Game 类之外,您还可以使用 GUI 轻松替换 Agent,一旦人类选择了一个动作,它就会返回一个有效的动作。


推荐阅读