You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将二十一点游戏中的两个重复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 07:24:06