二十一点游戏模拟器






4.26/5 (9投票s)
二十一点游戏模拟框架

引言
该项目提供了一个 Blackjack 游戏模拟器的框架。我不知道这是否会有用……嗯,对于赌徒来说,测试他们听说过的策略可能会有用。我有一个演示要做,所以我就胡乱拼凑了一个,最后得到了这个,所以还有很多地方需要改进。有关 Blackjack 游戏和规则的更多信息,可以参考 维基百科的文章。
Using the Code
解决方案包含五个组件
BlackJack
- GUI 应用程序Common
- 框架使用的通用类、枚举和接口Game
- 负责 Blackjack 游戏逻辑的组件Player
- 非常简单的计算机玩家HumanPlayer
- 人类玩家的简单接口

图:组件图
通用组件
通用组件包含
Deck
类 - 管理牌堆Hand
类 - 管理玩家的手牌IPlayer
接口 - Blackjack 玩家的接口PlayerOptions
枚举 - 玩家回合中的可能选项PlayerInGameStatus
枚举 - 当前玩家状态(玩或停牌)PlayerEndGameStatus
枚举 - 游戏结束时的玩家状态(赢家、输家……)
Game 组件调用 `IPlayer` 的方法来通知玩家事件。
游戏组件
游戏组件包含
PlayerStatus
类 - 玩家的包装类;此类存储玩家当前手牌和当前状态等数据,以防止作弊 :)Game
类 - Blackjack 游戏逻辑和控制PlayerDirectory
类 - 动态加载玩家组件
游戏的简化算法
- 开始新游戏
- 洗牌
- 开始新一轮
- 给所有玩家发两张牌
- 询问所有状态为“玩”的玩家是否想要另一张牌:如果有人想要,就再给他们发一张牌;如果有人不想要,就将其状态改为“停牌”。
- 当还有状态为“玩”的玩家时,重复步骤 5。
- 根据游戏规则比较玩家的手牌以宣布赢家和输家,更新玩家统计数据和游戏结束状态。
- 洗牌,发牌并将牌放回牌堆末尾。
- 如果这不是最后一轮,跳转到步骤 3。
上述算法在 `Game` 类的 `Round`、`BeginRound`、`PlayerTurn`、`GiveCardToPlayer` 和 `EndRound` 方法中实现。可以通过事件(`Game` 类的成员)来观察游戏。
OnRoundEnd
OnGameEnd
OnPlayerAdded
OnPlayerRemoved
OnPlayerListCleared
OnDealerChange
游戏运行在自己的线程中,并提供与 GUI 动画同步的方法,动画在每轮结束后播放。在每轮结束时,游戏线程调用 `WaitForAnimation`,直到 GUI 线程通过调用 `AnimationFinished` 发出动画完成的信号。`StartGame`、`StopGame`、`PauseGame` 和 `ContinueGame` 方法用于控制游戏。
玩家的加载和实例化
`PlayerDirectory` 类负责加载玩家组件和实例化玩家。在类的构造函数中,会检查 `.\Players` 文件夹中的所有程序集,如果包含玩家类,则会加载它们。玩家类的名称必须是 `MyPlayer`,并且必须在 `Player` 命名空间中。
可以通过调用 `LoadPlayer` 方法并指定程序集路径来添加其他程序集。要创建玩家的实例,只需调用 `CreateInstanceOfPlayer`,并根据需要指定程序集名称和构造函数参数。
playerDirectory.CreateInstanceOfPlayer("PlayerWithNameAndAge",
new object[]{ "Someone", 30 } );
简单玩家
具有简单逻辑的简单玩家
- “如果我有 Blackjack,我就停牌”
- “如果我有点数 21,我就停牌”
- “如果我的点数大于等于 17,我就停牌”
- “如果我的点数小于 17,我就再拿一张”
……可以用几行代码实现。
using Common;
namespace Player
{
public class MyPlayer : IPlayer
{
private Hand _myHand = new Hand();
private string _name;
public string Name { get { return _name; } }
public void NewRound(bool newGame,
bool isDealer, int dealersFirstCard, int numberOfDecks)
{ _myHand.Restart(); }
public PlayerOptions Turn(int left)
{
if (_myHand.IsBlackJack || _myHand.Values.Contains(21))
return PlayerOptions.Stand;
return _myHand.Values[0] <=
17 ? PlayerOptions.Hit : PlayerOptions.Stand;
}
public void GiveCard(int card) { _myHand.Add(card); }
public void EndRound(PlayerEndGameStatus status,
List<int> dealedCards) { }
public MyPlayer(string name) { _name = name; }
public MyPlayer() { _name = "strange name " +
GetHashCode().ToString(); }
}
}
框架项目
框架项目提供了一种便捷的方式来测试玩家逻辑,并配有完整的环境和项目设置。所有不必要的源代码都已删除。
附加信息
正如我所说,还有很多改进的空间(例如,牌应该由类而不是整数表示,动画代码可以改进)。此外,一些 Blackjack 规则尚未实现,例如玩家的分牌选项。
关注点
嗯,我的大学同学在制作更聪明的玩家方面玩得很开心,还举行了一点比赛。希望你也会喜欢。
历史
- 2007 年 8 月 24 日 -- 原文发布