菜单

扑克牌

相关源文件

目的与范围

本文档描述了纸牌组系统的面向对象设计。该实现提供了一个通用的纸牌游戏框架,并针对二十一点进行了特定扩展。该系统使用继承、抽象和封装等面向对象原则,模拟了纸牌游戏中发现的核心实体:牌、花色、手牌和牌组。

系统概览

纸牌组系统实现了一个灵活、可扩展的面向对象设计,可用于模拟各种纸牌游戏。当前实现侧重于标准的 52 张牌组,并针对二十一点进行了专门化。

来源: solutions/object_oriented_design/deck_of_cards/deck_of_cards.py1-118

核心组件

花色枚举

Suit 枚举代表了纸牌组中的四种标准花色。

来源: solutions/object_oriented_design/deck_of_cards/deck_of_cards.py6-11

牌类继承

抽象牌基类

Card 抽象基类提供了所有牌类型的基石,具有

  • 牌值和花色的属性
  • 可用性跟踪(用于管理已发出的牌)
  • 用于获取和设置值的抽象方法

来源: solutions/object_oriented_design/deck_of_cards/deck_of_cards.py14-29

BlackJackCard 实现

BlackJackCard 类扩展了抽象的 Card 类,增加了特定于二十一点的逻辑。

  • 对 A 和花牌(J、Q、K)的特殊处理
  • 值验证,确保牌值在 1 到 13 之间
  • 自定义值计算(花牌 = 10,A = 1)

来源: solutions/object_oriented_design/deck_of_cards/deck_of_cards.py32-58

手牌类继承

基础手牌类

Hand 类代表一副牌的集合,具有

  • 向手牌添加牌的方法
  • 通过累加牌值来计算分数

来源: solutions/object_oriented_design/deck_of_cards/deck_of_cards.py61-73

BlackJackHand 实现

BlackJackHand 类扩展了基础的 Hand 类,具有

  • 二十一点特定常量 (BLACKJACK = 21)
  • 自定义计分逻辑,处理由于 A 牌而可能存在的多个分数
  • 确定二十一点规则下最佳可能分数的逻辑

来源: solutions/object_oriented_design/deck_of_cards/deck_of_cards.py76-95

牌组类

Deck 类管理一副牌的集合,并具有以下功能:

  • 跟踪已发出哪些牌
  • 一次发一张牌
  • 计算剩余牌数
  • 洗牌(实现留作练习)

来源: solutions/object_oriented_design/deck_of_cards/deck_of_cards.py98-117

系统交互

下图说明了这些组件在典型的纸牌游戏场景中的交互方式。

来源: solutions/object_oriented_design/deck_of_cards/deck_of_cards.py61-117

实现细节

牌值处理

关键设计特性之一是如何处理牌值。

  1. 抽象的 Card 类将值定义为一个抽象属性,允许不同游戏实现不同的处理方式。
  2. BlackJackCard 为二十一点实现了自定义值逻辑。
    • 花牌(J、Q、K)的值始终为 10。
    • A 牌的值可以为 1(在牌级别管理)。
    • 值验证可确保牌在有效范围内(1-13)。

来源: solutions/object_oriented_design/deck_of_cards/deck_of_cards.py14-58

二十一点计分

BlackJackHand 类实现了二十一点的特定计分。

  1. 计算可能的分数,考虑 A 牌(作为 1 或 11)。
  2. 根据二十一点规则确定最佳分数。
    • 优先选择 21 以下或等于 21 的分数。
    • 在超过 21 分的情况下,选择最低分。
    • 在 21 分以下或等于 21 分的情况下,选择最高分。

这种专门的计分逻辑封装在 BlackJackHand 类中,保持基础 Hand 类的通用性和可重用性。

来源: solutions/object_oriented_design/deck_of_cards/deck_of_cards.py76-95

设计模式与原则

纸牌组系统展示了多种面向对象的设计模式和原则。

模式/原则实现
抽象Card 抽象基类定义了接口,而没有实现。
继承BlackJackCardBlackJackHand 扩展了基类,并具有特定行为。
封装牌值验证和状态管理被封装在相应的类中。
单一职责每个类都有一个清晰、专注的职责(例如,Deck 管理牌的集合)。
开闭原则系统可以通过不修改核心类来扩展以适应新的纸牌游戏。

来源: solutions/object_oriented_design/deck_of_cards/deck_of_cards.py1-118

扩展系统

面向对象设计使得扩展系统以适应其他纸牌游戏变得非常简单。

  1. 创建新的牌类,扩展抽象的 Card 类。
  2. 在这些类中实现特定于游戏的牌值逻辑。
  3. 创建专门的 Hand 类,包含特定于游戏的计分规则。
  4. 按原样使用 Deck 类,或在需要时扩展它。

例如,要实现扑克,您需要创建一个 PokerCard 类和一个 PokerHand 类,并包含特定于扑克的牌型评估逻辑。

来源: solutions/object_oriented_design/deck_of_cards/deck_of_cards.py1-118

限制和注意事项

  • BlackJackHand 中的 possible_scores() 方法尚未完全实现,但它负责计算所有可能的 A 牌分数(计为 1 或 11)。
  • Deck 中的 shuffle() 方法留作练习实现。
  • 该系统目前不处理大小王牌或其他特殊牌。
  • 没有用于创建标准 52 张牌组的工厂方法。

来源: solutions/object_oriented_design/deck_of_cards/deck_of_cards.py93-117