我对游戏开发比较陌生,所以我决定从头开始创建一个体验和娱乐的爱好项目.特定游戏类似于被称为Three Card Brag的扑克游戏.游戏在电影Lock,Stock和Two Smoking Barrels中播放.
我一直在阅读有关游戏开发的一些关于SO的主题,但主要是这个问题.这有助于改进我创建对象的原始方式.
我遇到的一个特殊问题是定义游戏状态.我最初的方法是将所有内容分开(例如将芯片堆栈保留在一个Player
类中),但在阅读了我之前提到的问题的响应之后,似乎所有可能的游戏状态都应保持在一个GameState
对象中.我想出的基本上是这样的:
abstract class CardGameState { protected List_Players; protected Player _CurrentPlayer; protected Dictionary _Chips; protected Dictionary _CurrentHand; protected Dictionary _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
类中,我认为这不是理想的.
基本上,我的问题是:我能否拥有两个世界中最好的东西,这样我才能准确表示游戏状态,同时将所有数据专门与游戏状态中的对象保持在给定对象内?
在线游戏中,使用命令模式(您的IAction)是标准的,经过验证的方法.从玩家的角度来看,它不是面向对象的,但是动作是面向对象的,所以从纯粹的理论角度来看,它是一个坚实的设计模式,我想.在实践中,这就是我见过的每一个成功的在线游戏如何实现它,但请注意,动作游戏通常使用非常小的谨慎动作/数据包,直到它实际上成为各种各样的流.
编辑:
在我回答这个问题很长一段时间之后,我回到这里并意识到这个问题的另一个解决方案是实现GameState的玩家,游戏等......来自具有Apply(IAction动作)成员的IState类.这种方式对象对自己应用操作,而不是让应用程序对对象应用操作,这会将操作和状态映射到访问者模式而不是命令模式.这两种解决方案都可以工作,访问者具有更大的开销和更多的封装,而命令是更简单的解决方案,封装更少.