多人纸牌游戏的游戏架构和设计策略

时间:2009-03-03 03:36:08

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

我对游戏开发比较陌生,所以我决定从头开始创建一个体验和娱乐的爱好项目。特定游戏类似于称为Three Card Brag的扑克。游戏在电影 Lock,Stock and Two Smoking Barrels 中播放。

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

我遇到的一个特殊问题是定义游戏状态。我最初的方法是将所有内容分开(例如将芯片堆栈保留在Player类中)但在阅读了我之前提到的question的响应之后,似乎应保持游戏的所有可能状态在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对象。

另一方面,如果玩家要提高赌注,我会创建一个RaiseAction来实现IAction,但IAction界面只接受当前的游戏状态,如果芯片堆栈存储在Player类中,我不相信这是理想的。

基本上,我的问题是:我是否可以充分利用这两个世界,以便能够准确表示游戏状态,同时将所有数据专门与游戏状态中的对象保持在给定对象内?

2 个答案:

答案 0 :(得分:6)

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

修改:

在我回答这个问题很长一段时间之后,我回到这里并意识到另一个解决这个问题的方法是实现GameState的玩家,套牌等...来自 IState 类,带有< strong>申请(执行行动)成员。这种方式对象对自己应用操作,而不是让应用程序对对象应用操作,这会将操作和状态映射到visitor-pattern而不是命令模式。这两种解决方案都可以工作,其中访问者具有更大的开销和更多的封装,而命令是更简单的解决方案,封装更少。

答案 1 :(得分:1)

似乎你可能会出于对象的方式对象进行对象化...

看起来像Bob Martin的经典bowling game问题。

编辑: - 总结 -
它是一个很长的阅读,但基本上,通过TDD和重构,一个保龄球评分应用程序从一个具有大量的类和多态的大型集群到20或30个优雅的代码行。为什么?因为他们并不是真的需要首先出现在那里