如何将二十一点游戏中的两个重复for循环改写为单个函数
21点游戏发牌逻辑优化方案
首先原代码存在几个可以优化的点:
- 重复写了两次发牌逻辑,冗余不好维护
- 仅限制了单个玩家的手牌不重复,没有限制两个玩家的手牌全局不重复,不符合真实卡牌规则
- 循环+跳过重复的逻辑有可能出现循环次数耗尽但手牌数量不足的问题,比如连续两次抽到重复牌,最终手牌只有1张
- 已经定义了
deal_cards函数但实际发牌时没有调用,属于冗余代码
推荐采用先洗牌再按顺序取牌的逻辑实现,既符合真实21点的发牌规则,也能完全满足你要封装函数、分配两套不同卡牌的需求,代码如下:
import random print("Welcome to Blackjack!") # 单副牌的牌组配置 cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10] def init_shoe(card_deck, deck_count=1): """初始化牌堆,支持多副牌配置,默认使用1副牌""" shoe = card_deck * deck_count random.shuffle(shoe) return shoe def deal_cards(shoe, number=2): """从牌堆中取出指定数量的牌,默认取2张初始手牌""" hand = shoe[:number] # 已发出的牌从牌堆移除,避免重复发放 del shoe[:number] return hand # 初始化打乱后的全局牌堆 game_shoe = init_shoe(cards) # 分别发牌,两套卡牌天然不重复 user_cards = deal_cards(game_shoe) computer_cards = deal_cards(game_shoe) print(user_cards) print(computer_cards)
如果不需要支持多副牌,也可以用更精简的写法:
import random print("Welcome to Blackjack!") cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10] # 直接打乱牌组 random.shuffle(cards) def deal_cards(shoe, count=2): res = shoe[:count] del shoe[:count] return res user_cards = deal_cards(cards) computer_cards = deal_cards(cards) print(user_cards) print(computer_cards)
该方案的优势:
- 所有发牌逻辑统一封装,后续修改规则只需要调整
deal_cards函数即可 - 全局牌堆统一管理,天然不会出现不同玩家拿到重复卡牌的情况
- 支持多副牌扩展,符合正规21点的游戏规则
- 不需要循环判断去重,执行效率更高,也不会出现手牌数量不足的问题
内容的提问来源于stack exchange,提问作者Pratik Thorat
相关产品推荐
相关产品推荐

