跳到主要内容

Python 扑克牌程序实战:洗牌与发牌功能的实现

前面我们已经完成了扑克牌对象的创建,现在这副牌还是按顺序排列的。实际打牌当然不能这样,我们需要先把牌打乱,再一张张发出去。这篇文章就带大家完成洗牌和发牌两个核心功能,并把整副牌的逻辑串起来测试一遍。

一、实现目标​

在 Deck 类中补充两个方法:

  1. 洗牌(shuffle):把初始化好的有序牌堆随机打乱。
  2. 发牌(deal):每次调用从牌堆顶部弹出一张牌。

洗牌依赖 Python 内置的 random 模块,发牌则利用列表的 pop() 方法实现。

二、洗牌功能的实现​

洗牌的核心是 random.shuffle()。它接收一个列表,直接在原列表上做随机打乱,不会返回新列表。

先在文件顶部导入 random 模块,然后在 Deck 类中定义 shuffle 方法,把 self.cards 传进去:

import random

class Deck:
def __init__(self):
suits = ['♠', '♥', '♣', '♦']
ranks = ['A'] + [str(i) for i in range(2, 11)] + ['J', 'Q', 'K']
self.cards = [Card(suit, rank) for suit in suits for rank in ranks]

def shuffle(self):
random.shuffle(self.cards)

这里有一个容易踩的坑:random.shuffle() 执行后没有任何返回值,它改变的是传入的原始列表本身。所以调用完洗牌后,直接查看 self.cards 就能看到打乱后的结果。

为了先验证这个方法的效果,我们可以在 IDLE 中单独测试:先生成一副有序的牌,调用 random.shuffle(cards),再输出 cards 对比前后变化。

random.shuffle 打乱牌堆前后的对比效果

可以看到,原本按黑桃 A、黑桃 2、黑桃 3 顺序排列的牌,经过 shuffle 后顺序完全打乱、毫无规律。这就说明洗牌逻辑是有效的。

三、发牌功能的实现​

洗牌完成后,牌堆 self.cards 就是一个打乱顺序的列表。发牌就是从列表顶部取牌,用 pop() 弹出即可:

    def deal(self):
return self.cards.pop()

每次调用 deal(),都会从 self.cards 中弹出一张牌并返回,同时牌堆里就少了一张。连续调用多次,就相当于连续发牌。

image-20261028152726996

四、整体测试​

把洗牌和发牌串起来跑一遍。先实例化 Deck 得到整副牌,遍历输出确认顺序正常:

deck = Deck()

for card in deck.cards:
print(card)

因为 Card 类中定义了 __str__ 方法,输出时会自动显示花色加点数,所以遍历打印出来的就是一副可读的、有顺序的扑克牌。

实例化 Deck 后遍历输出有序的整副扑克牌

接着调用 deck.shuffle() 洗牌,再次遍历输出:

deck.shuffle()

for card in deck.cards:
print(card)

运行后对比两次输出,可以看到洗牌后的顺序已经完全改变,说明 shuffle 方法在类中同样生效。

调用 deck.shuffle() 后整副牌顺序被打乱

最后测试发牌。连续调用四次 deal(),把每次返回的牌分别赋值给变量再打印:

card1 = deck.deal()
card2 = deck.deal()
card3 = deck.deal()
card4 = deck.deal()

print(card1)
print(card2)
print(card3)
print(card4)

运行结果会依次输出四张牌,它们正是洗牌后牌堆最上面的四张,且每次调用只弹出一张,符合“从上往下发牌”的预期。

连续调用 deal() 发出四张牌的输出结果

五、小结​

到这里,一副扑克牌的完整逻辑就实现了:

  • 实例化 Deck 时,初始化方法自动生成一副有规律的牌;
  • 调用 shuffle() 时,借助 random.shuffle() 原地打乱牌堆;
  • 调用 deal() 时,通过 pop() 从牌堆顶部弹出一张牌。

三个环节各司其职,组合起来就构成了洗牌、发牌的基础流程,后续做更复杂的发牌规则(比如庄家与玩家轮流发牌)时,直接在这个基础上扩展即可。

课程推荐

想系统学习这门课程?

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

查看课程详情