【问题标题】:Game architecture and design strategy for a multiplayer card game多人纸牌游戏的游戏架构和设计策略
【发布时间】:2009-03-03 03:36:07
【问题描述】:

我对游戏开发比较陌生,所以我决定从头开始创建一个爱好项目,既可以体验又可以娱乐。具体游戏类似于扑克牌Three Card Brag。该游戏在电影 Lock, Stock 和 Two Smoking Barrels 中进行。

我一直在阅读一些关于游戏开发的 SO 主题,但主要是 this question。这有助于改进我创建对象的原始方式。

我遇到的一个特殊问题是定义游戏状态。我最初的方法是将所有内容分开(例如,将筹码堆放在Player 类中),但在阅读了我之前提到的question 的回复之后,似乎游戏的所有可能状态都应该保持在@987654325 中@ 目的。我想出的基本上是这样的:

abstract class CardGameState
{
    protected List<Player> _Players;
    protected Player _CurrentPlayer;
    protected Dictionary<Player, int> _Chips;
    protected Dictionary<Player, Hand> _CurrentHand;
    protected Dictionary<Player, PlayerStatuses> _PlayerStatus; // PlayerStatuses.InHand, PlayerStatuses.Folded, PlayerStatuses.SittingOut, etc.
    /* etc. */

每个CardGameState 都被某些操作修改:

public interface IAction
{
    string Name { get; }

    CardGameState Apply(CardGameState state);
    bool IsLegal(CardGameState state);
}

现在我非常强烈地感觉这违背了面向对象编程的目的,因为与玩家相关的数据(在这种情况下,他的筹码量、手牌和当前状态)没有被封装Player 对象。

另一方面,如果玩家加注,我将创建一个实现IActionRaiseAction,但IAction 接口只接受当前游戏状态,我不相信如果芯片堆栈存储在Player 类中,那将是理想的。

基本上,我的问题是:我是否可以两全其美,这样我就可以准确表示游戏状态,同时将所有与游戏状态中的对象特别相关的数据保存在给定对象中?

【问题讨论】:

  • 嗨,约翰,我刚刚回顾了这个问题,并意识到您还可以通过使用访问者模式将 IAction.Apply 替换为 IState.Apply 来获得两全其美的效果。现在可能为时已晚,但无论如何它可能会作为未来的参考。

标签: c# .net design-patterns playing-cards


【解决方案1】:

在在线游戏中,使用command-pattern(您的 IAction)是标准且经过验证的方法。它不是玩家意义上的面向对象,但动作是面向对象的,所以从纯理论的角度来看,我猜它是一个可靠的设计模式。在实践中,我见过的每一个成功的在线游戏都是这样实现它的,但请注意,动作游戏通常使用非常小的谨慎动作/数据包,直到它实际上变成某种流。

编辑:

在我回答这个问题很久之后,我回到这里并意识到这个问题的另一种解决方案是实现 GameState 的 Players、Decks 等...作为派生自 IState 类的 IState 类strong>应用(IAction 操作) 成员。这样,对象对自己应用操作,而不是让应用程序对对象应用操作,这会将操作和状态映射到 visitor-pattern 而不是命令模式。两种解决方案都可以,visitor 的开销更大,封装更多,而 command 是更简单的解决方案,封装更少。

【讨论】:

  • 所以我想问题归结为可变性,例如玩家的名字将驻留在 Player 类中,因为它不会受到任何游戏动作的影响。这意味着可以通过游戏中任何可能的操作更改的所有内容都将直接存储在游戏状态中。
  • 在某种程度上是的(名称也可以更改)。但是玩家状态是游戏状态的子部分。
【解决方案2】:

看起来你可能是为了面向对象而将它面向对象...

似乎是 Bob Martin 的经典 bowling game 问题。

编辑:-总结-
这是一个漫长的阅读过程,但基本上,通过 TDD 和重构,保龄球得分应用程序从一个包含大量类和多态性的巨大集群变成了 20 或 30 行优雅的代码。为什么?因为他们一开始并不真的需要在那里

【讨论】:

  • 读得好——虽然我尝试过在没有 OO 操作的情况下编写此应用程序,但我唯一能挽救的就是用于手动比较的类。其余的是控制游戏状态的程序性尝试,很容易忘记每个玩家的行为如何修改它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 2012-07-27
相关资源
最近更新 更多