discord.py Blackjack抽牌函数返回None问题及去重算法优化求助
问题根源分析
原代码存在两个核心问题:
- 每次调用
deck()都会重新生成并洗牌整副牌,完全违背真实抽牌逻辑——你应该维护一副全局的、已洗牌的牌组,而非每次抽牌都重建牌组。 - 递归分支无返回值:当抽到重复牌时,调用
Test.deck(self)但未返回该调用的结果,导致当前函数执行到return时无有效返回值,最终返回None。
优化方案:维护全局洗牌牌组
正确思路是在类初始化时生成并洗牌完整牌组,后续抽牌直接从该牌组取牌,天然避免重复,无需额外去重检查。
修改后代码示例:
import random class BlackJackGame: def __init__(self): # 初始化时生成整副牌并完成洗牌 card_suits = ["Club ", "Diamond ", "Spade ", "Heart "] card_ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "K", "Q", "A"] self.deck = [suit + rank for suit in card_suits for rank in card_ranks] random.shuffle(self.deck) def draw_card(self): # 牌组抽完时自动重新洗牌 if not self.deck: card_suits = ["Club ", "Diamond ", "Spade ", "Heart "] card_ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "K", "Q", "A"] self.deck = [suit + rank for suit in card_suits for rank in card_ranks] random.shuffle(self.deck) return self.deck.pop()
原递归逻辑的修复(不推荐)
如果非要保留原思路(不建议,效率极低),需修复递归的返回逻辑:
def deck(self): card_type = ["Club ", "Diamond ", "Spade ", "Heart "] card_nums = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "K", "Q", "A"] cards_total = [i + j for i in card_type for j in card_nums] random.shuffle(cards_total) pop_card = cards_total.pop() if pop_card in self.overlap_check: # 必须返回递归调用的结果 return self.deck() self.overlap_check.append(pop_card) return pop_card
此方案弊端明显:每次抽牌都要重建、洗牌整副牌,牌组快抽完时递归深度会急剧上升,容易触发Python递归深度限制。
为什么推荐全局牌组方案?
- 完全贴合真实二十一点游戏规则:一副牌抽完后重新洗牌。
- 彻底规避重复抽牌问题,无需额外去重逻辑。
- 性能更优,无冗余的牌组生成和递归操作。
内容的提问来源于stack exchange,提问作者Luminous Lunetzsche
相关产品推荐
相关产品推荐

