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

Blackjack游戏重玩时手牌不重置问题技术求助

解决Blackjack游戏重玩时手牌不重置&发牌重复问题

问题根源

  • 全局变量(playerHand、dealerHand、deck、playerIn、dealerIn)未在重玩时重置,导致复用旧状态
  • 初始发牌逻辑在全局作用域仅执行一次,重玩时不会重新发牌
  • 牌堆(deck)在第一次游戏后被修改,重玩时使用的是剩余牌甚至空牌堆

修复方案

  1. 将需要重置的变量移至play函数内部,确保每次调用play都初始化全新状态
  2. 把初始发牌的循环逻辑放入play函数开头,保证每局游戏都重新发初始手牌
  3. 每次游戏重新生成完整的牌堆,避免复用剩余牌
  4. 调整tryAgain函数,确保重玩时正确调用初始化后的play

修复后的完整代码

import random

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 tryAgain(name):
    again = input("Would you like to play again, type yes or no: ").lower()
    if again == "yes":
        print("Ok")
        play(name)
    elif again == "no":
        print(f"Bye {name}")

def revealDealerHand(dealerHand):
    if len(dealerHand) == 2:
        return dealerHand[0]
    elif len(dealerHand) > 2:
        return dealerHand[0], dealerHand[1]

def play(name):
    # 每局游戏初始化所有状态
    playerIn = True
    dealerIn = True
    # 重新生成完整牌堆
    deck = [2, 3, 4, 5, 6, 7, 8, 9, 10] * 4 + ['J', 'Q', 'K', 'A'] * 4
    playerHand = []
    dealerHand = []

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

    while playerIn or dealerIn:
        print(f"\nDealer has {revealDealerHand(dealerHand)} and X")
        print(f"\nYou have {playerHand} for a total of {total(playerHand)}")
        stayOrHit = None
        if playerIn:
            stayOrHit = input("\nWould you like to stay or hit (type 1 for stay and 2 for hit): ").lower()
        
        # 庄家逻辑
        if total(dealerHand) > 16:
            dealerIn = False
        else:
            dealCard(dealerHand, deck)
        
        # 玩家逻辑
        if stayOrHit == "1":
            playerIn = False
        elif stayOrHit == "2":
            dealCard(playerHand, deck)
        
        # 结束条件判断
        if total(playerHand) >= 21:
            break
        elif total(dealerHand) >= 21:
            break

    # 结算逻辑
    print(f"\nYou have a hand of {playerHand} for a total of {total(playerHand)} and the dealer has {dealerHand} for a total of {total(dealerHand)}")
    if total(playerHand) == 21:
        print(f"BLACKJAAACK! Nice one {name}")
    elif total(dealerHand) == 21:
        print("BLACKJACK, Dealer wins you lose, HA!")
    elif total(playerHand) > 21:
        print("You bust loser, Dealer wins.")
    elif total(dealerHand) > 21:
        print(f"The dealer busts, You win {name}!")
    elif 21 - total(dealerHand) < 21 - total(playerHand):
        print("Dealer Wins, loser.")
    elif 21 - total(playerHand) < 21 - total(dealerHand):
        print(f"You Win {name}!")
    
    tryAgain(name)

name = input("Please type your name: ")
play(name)

额外优化点

  • 将deck作为参数传入dealCard函数,避免依赖全局变量,提高代码模块化
  • 优化total函数中对数字牌的判断,用isinstance更准确
  • 调整玩家stay的逻辑,将playerIn设为False而不是直接break,保证庄家逻辑能正常走完
  • 结算时统一打印手牌信息,减少重复代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 15:45:43