English 中文(简体)
一个多人在线卡牌游戏的游戏结构和设计策略
原标题:
  • 时间:2009-03-03 03:36:07
  •  标签:

我对游戏开发相对较新,因此我决定从零开始创建一个业余项目,以获得经验和娱乐。具体的游戏类似于扑克,称为 三张牌。这个游戏在电影《抢钱夺宝》中出现过。

我一直在阅读有关游戏开发的一些主题,尤其是这个问题。 这有助于重构我最初创建对象的方法。

我遇到的一个特定问题是定义游戏状态。我的初始方法是分离一切(例如将筹码堆放在Player类内部),但在阅读我先前提到的问题的回答后,似乎所有可能的游戏状态都应该在一个GameState对象中维护。我设计的基本上是这样的:

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对象中。

另一方面,如果玩家要提高赌注,我将创建一个实现IAction的RaiseAction,但IAction接口仅接受当前游戏状态,这不是存储在Player类中的筹码堆栈理想的解决方案。

我的问题其实是:我能否两全其美,即在保持游戏状态的精确表示的同时,将所有与游戏状态中的特定对象相关的数据都保存在其给定对象内?

最佳回答

在在线游戏中,使用命令模式(您的IAction)是标准且经过验证的方法。从玩家的角度来看,它不是面向对象的,但动作是面向对象的,因此从纯理论角度来看,它是一种坚实的设计模式,我想。实践上,这就是我见过的每个成功的在线游戏实现方式,但请注意,动作游戏通常使用非常小的离散动作/数据包,直到它实际上变成一种流的形式。

编辑:

在我解答完这个问题后,很久以后我回到这里,意识到另一个解决这个问题的方法是将GameState的Players,Decks等实现为从IState类派生的类,带有一个Apply(IAction action)成员。这样对象就可以将操作应用于自身,而不是让应用程序在对象上应用操作,这将将操作和状态映射到访问者模式而不是命令模式。任何一种解决方案都可以工作,其中访问者的开销更大,封装性更强,而命令则是更简单的解决方案,封装性更少。

问题回答

好像你可能只是为了面向对象而将其面向对象化。

看起来像是Bob Martin经典的保龄球游戏问题。

EDIT: -Summary-
Its a long read, but basically, through TDD and refactoring, a bowling scoring application went from a huge cluster with lots of Classes and polymorphism to 20 or 30 elegant lines of code. Why? Because they didn t really need to be there in the first place





相关问题
热门标签