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

Python实现21点游戏重玩功能:如何复用已跳出的循环?

给Python版21点游戏添加重玩功能的方案

先修正原代码的小问题

你原代码里有个语法错误:playerIn == False 是比较运算符,应该改成赋值 playerIn = False,否则玩家选择“stay”后不会退出自己的回合。

核心修改思路

要实现重玩,就得把单局游戏的全部流程(包括初始化牌堆、发牌、游戏循环、胜负结算)放到一个外层循环里,每局结束后询问玩家是否继续,以此控制外层循环的启停。同时要注意,每局开始前必须重置所有游戏变量(牌堆、手牌、玩家/庄家状态),否则会因为上一局的残留数据导致逻辑混乱。

修改后的完整代码

import random

name = input("请输入你的名字: ")

# 定义生成完整牌堆的函数,方便每局重置
def create_deck():
    return [2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 3, 4, 5, 6, 7, 8, 9, 10,
            2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 3, 4, 5, 6, 7, 8, 9, 10,
            'J', 'Q', 'K', 'A', 'J', 'Q', 'K', 'A', 'J', 'Q', 'K', 'A',
            'J', 'Q', 'K', 'A']

# 发牌函数
def dealCard(turn, deck):
    card = random.choice(deck)
    turn.append(card)
    deck.remove(card)

# 计算手牌总值
def total(turn):
    total = 0
    face = ['J', 'K', 'Q']
    for card in turn:
        if isinstance(card, int) and 1 <= card <= 10:
            total += card
        elif card in face:
            total += 10
        else:
            total += 1 if total > 11 else 11
    return total

# 显示庄家手牌(隐藏第二张)
def revealDealerHand(dealerHand):
    if len(dealerHand) == 2:
        return dealerHand[0]
    elif len(dealerHand) > 2:
        return dealerHand[0], dealerHand[1]

# 重玩控制外层循环
play_again = True
while play_again:
    # 每局初始化游戏变量
    playerIn = True
    dealerIn = True
    deck = create_deck()
    playerHand = []
    dealerHand = []

    # 初始发牌
    for _ in range(2):
        dealCard(dealerHand, deck)
        dealCard(playerHand, deck)

    # 核心游戏循环(你之前高亮的部分)
    while playerIn or dealerIn:
        print(f"\n庄家手牌: {revealDealerHand(dealerHand)} 和 X")
        print(f"\n你的手牌: {playerHand},总值: {total(playerHand)}")
        
        if playerIn:
            stayOrHit = input("\n要停牌还是要牌?(输入1停牌,2要牌): ")
        
        # 庄家逻辑:大于16则停牌
        if total(dealerHand) > 16:
            dealerIn = False
        else:
            dealCard(dealerHand, deck)
        
        # 玩家逻辑
        if playerIn:
            if stayOrHit == "1":
                playerIn = False
            else:
                dealCard(playerHand, deck)
        
        # 结束循环条件:玩家或庄家爆牌/ blackjack
        if total(playerHand) >= 21 or total(dealerHand) >= 21:
            break

    # 胜负结算
    print(f"\n你的手牌: {playerHand},总值: {total(playerHand)}")
    print(f"庄家手牌: {dealerHand},总值: {total(dealerHand)}")
    
    if total(playerHand) == 21:
        print(f"BLACKJACK!牛啊 {name}!")
    elif total(dealerHand) == 21:
        print("BLACKJACK,庄家赢了,你输了!")
    elif total(playerHand) > 21:
        print("你爆牌了,庄家赢了!")
    elif total(dealerHand) > 21:
        print(f"庄家爆牌了,你赢了 {name}!")
    elif 21 - total(dealerHand) < 21 - total(playerHand):
        print("庄家赢了!")
    else:
        print(f"你赢了 {name}!")

    # 询问是否重玩
    choice = input("\n要不要再玩一局?(输入y继续,其他退出): ").lower()
    play_again = choice == 'y'

关键改动说明

  1. 新增外层重玩循环:用while play_again:包裹整个单局流程,玩家每局结束后选择是否继续。
  2. 重置游戏变量:每局开始前重新生成完整牌堆、清空手牌、重置playerIn和dealerIn状态,避免上一局数据干扰。
  3. 修复赋值错误:把playerIn == False改成playerIn = False,确保玩家选择停牌后能退出自己的回合。
  4. 优化牌堆管理:新增create_deck()函数,每次重玩都生成全新的完整牌堆,解决原代码中牌堆逐渐耗尽的问题。
  5. 调整函数参数:给dealCard和revealDealerHand传入对应参数,让函数更独立,避免依赖全局变量的副作用。

内容的提问来源于stack exchange,提问作者Ivanoo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:05:23