跳到主要内容

用 Python 实现 21 点游戏:Game 类初始化与发牌逻辑

前面我们已经完成了牌堆(Deck)和手牌(Hand)等基础类,这一节把核心的 Game 类搭起来。整个游戏的业务逻辑都集中在这个类里,最终我们就是通过不断调用它来完成一局游戏。本文完成两件事:初始化一副牌并洗牌、给玩家和庄家各发两张牌。

一、目标拆解​

Game 类初始化时需要依次完成:

  1. 创建一副牌(调用 Deck 类),保存为 self.deck;
  2. 洗牌(shuffle);
  3. 创建玩家手牌 self.player 和庄家手牌 self.dealer(均为 Hand 实例);
  4. 发初始牌:玩家一张、庄家一张、玩家一张、庄家一张,共四张。

说明:两张牌无论如何都不会超过 21 点,所以开局固定各发两张;玩家牌全部亮出,庄家保留一张底牌。

二、代码实现​

1. 初始化牌堆与手牌​

在 Game 类的 __init__ 中,先准备好牌、洗好牌,再实例化玩家和庄家的手牌对象:

class Game:
def __init__(self):
# 创建一副牌
self.deck = Deck()
# 洗牌
self.deck.shuffle()
# 玩家手牌
self.player = Hand()
# 庄家手牌
self.dealer = Hand()

这里在 Game 内部调用其他类(Deck、Hand)是完全可行的,self.deck 就是一副牌对象。

Game 类 init 中创建牌堆、洗牌并实例化玩家与庄家手牌

2. 编写发牌方法​

新增一个发牌初始化方法,按"玩家—庄家—玩家—庄家"的顺序各发一张。每次发牌都从牌堆调用 deal() 取出一张牌(即 Card 对象),再通过 add_card() 加入对应手牌:

    def deal_initial(self):
# 玩家和庄家各发两张牌(共四张)
self.player.add_card(self.deck.deal())
self.dealer.add_card(self.deck.deal())
self.player.add_card(self.deck.deal())
self.dealer.add_card(self.deck.deal())

关键点在于 self.deck.deal() 的返回值:它返回的就是一张牌,也就是 Card 类的一个对象,正好作为 add_card() 的参数。这一点在之前讲解 Deck 类时已经用示例代码验证过,这里直接拿来用即可。

发牌方法中玩家与庄家各发两张牌,共四张

三、测试与结果​

运行后,Game 实例化时会自动完成建牌、洗牌、发牌。此时:

  • self.player 手中有 2 张牌,全部亮出;
  • self.dealer 手中有 2 张牌,其中一张作为底牌保留。

如果对 deal() 的返回类型仍有疑问,可以临时把之前的示例代码还原,打印一次 self.deck.deal(),确认得到的是 Card 对象,再继续后续逻辑。

四、小结​

本节完成了 Game 类的骨架:

  • __init__:建牌 → 洗牌 → 创建玩家/庄家手牌;
  • deal_initial:按顺序各发两张,共四张;
  • 发牌链路为 Deck.deal() 取牌 → Hand.add_card() 入牌。

下一步就可以在这个基础上继续实现玩家要牌、庄家逻辑与胜负判定。

课程推荐

想系统学习这门课程?

你已阅读完本文。需要更完整的知识体系,可以继续了解「Vibe Coding 实战课程」。

查看课程详情