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

Python Blackjack项目遇IndexError: list index out of range错误求助

Python二十一点游戏IndexError问题修复

问题概述

开发二十一点游戏时触发IndexError: list index out of range,报错指向player1cards[0]或player1cards[1],提示这两个列表为空。调用draw_cards函数试图修改全局列表但未生效,尝试过多种调试方法仍未解决。

核心错误原因

  1. 局部变量覆盖全局变量:rungame函数内部声明player1cards = []和dealercards = [],创建局部变量覆盖全局同名列表。draw_cards修改的是全局列表,但rungame后续访问的是局部空列表,导致索引越界。
  2. 重复初始化与无效调用:rungame开头调用draw_cards后,随即被局部变量初始化清空;下注后再次初始化列表并调用draw_cards,此时列表仍是局部变量,若抽卡逻辑异常会导致列表为空。
  3. 抽卡时的错误删除:hit和庄家抽卡环节执行del cardlist[card],但card是全局旧变量,并非当前抽到的dealcard,错误删除卡片导致cardlist提前耗尽,后续抽卡失败。
  4. 已抽卡片列表重复初始化:全局范围内重复赋值dealt_cards=[],导致抽卡去重逻辑失效,可能出现无限循环或抽卡失败。

修复步骤

  1. 移除局部变量声明:删除rungame函数内的player1cards = []和dealercards = [],确保使用全局列表。
  2. 修复卡片删除逻辑:将del cardlist[card]替换为用dealt_cards记录已抽卡片,避免直接修改cardlist。
  3. 清理重复初始化:删除全局范围内的第二次dealt_cards=[]赋值,保留初始的dealt_cards = []。
  4. 移除无效抽卡调用:删除rungame开头的draw_cards()调用,只保留下注后的一次抽卡,并在每次游戏前重置dealt_cards。

优化建议

  • 避免全局变量:改用函数参数、返回值或类封装游戏状态(如玩家手牌、庄家手牌、筹码),减少全局变量带来的意外覆盖问题。
  • 优化牌组管理:生成完整牌组列表并洗牌,用pop()方法抽卡,替代从字典中随机选择的逻辑,更符合实际发牌流程。
  • 封装抽卡逻辑:将抽卡过程封装成独立函数,在draw_cards、hit、庄家抽卡时复用,减少代码重复。
  • 使用enumerate遍历:打印手牌时用for card in dealercards:替代索引遍历,代码更简洁易读。

修复后的完整代码

import random
import time

def cash_out():
    global playerchips
    total_value = playerchips[0] * 10 + playerchips[1] * 5 + playerchips[2] * 1
    print(f"\nYou are cashing out. You have a total of ${total_value}.")
    exit()

print("Welcome to the solo-blackjack casino.py. You will start with $45 dollars in chips.")

player1cards = []
dealercards = []
dealt_cards = []

cardlist = {
    '2 of Spades': 2,
    '2 of Hearts': 2,
    '2 of Clubs': 2,
    '2 of Diamonds': 2,
    '3 of Spades': 3,
    '3 of Hearts': 3,
    '3 of Clubs': 3,
    '3 of Diamonds': 3,
    '4 of Spades': 4,
    '4 of Hearts': 4,
    '4 of Clubs': 4,
    '4 of Diamonds': 4,
    '5 of Spades': 5,
    '5 of Hearts': 5,
    '5 of Clubs': 5,
    '5 of Diamonds': 5,
    '6 of Spades': 6,
    '6 of Hearts': 6,
    '6 of Clubs': 6,
    '6 of Diamonds': 6,
    '7 of Spades': 7,
    '7 of Hearts': 7,
    '7 of Clubs': 7,
    '7 of Diamonds': 7,
    '8 of Spades': 8,
    '8 of Hearts': 8,
    '8 of Clubs': 8,
    '8 of Diamonds': 8,
    '9 of Spades': 9,
    '9 of Hearts': 9,
    '9 of Clubs': 9,
    '9 of Diamonds': 9,
    '10 of Spades': 10,
    '10 of Hearts': 10,
    '10 of Clubs': 10,
    '10 of Diamonds': 10,
    'Jack of Spades': 10,
    'Jack of Hearts': 10,
    'Jack of Clubs': 10,
    'Jack of Diamonds': 10,
    'Queen of Spades': 10,
    'Queen of Hearts': 10,
    'Queen of Clubs': 10,
    'Queen of Diamonds': 10,
    'King of Spades': 10,
    'King of Hearts': 10,
    'King of Clubs': 10,
    'King of Diamonds': 10,
    'Ace of Spades': 11,
    'Ace of Hearts': 11,
    'Ace of Clubs': 11,
    'Ace of Diamonds': 11
}

def draw_cards():
    global player1cards, dealercards, dealt_cards

    # 清空之前的手牌
    player1cards.clear()
    dealercards.clear()
    
    for _ in range(2):  # 给玩家和庄家各发两张牌
        # 玩家抽牌
        card = random.choice(list(cardlist.keys()))
        while card in dealt_cards:
            card = random.choice(list(cardlist.keys()))
        player1cards.append(card)
        dealt_cards.append(card)
        
        # 庄家抽牌
        card = random.choice(list(cardlist.keys()))
        while card in dealt_cards:
            card = random.choice(list(cardlist.keys()))
        dealercards.append(card)
        dealt_cards.append(card)

def calculate_hand_value(cards):
    value = 0
    aces = 0
    for card in cards:
        card_value = cardlist[card]
        if card_value == 11:
            aces += 1
        value += card_value
    while value > 21 and aces:
        value -= 10
        aces -= 1
    return value

def is_soft_17(cards):
    # 判断庄家是否拿到软17
    value = calculate_hand_value(cards)
    if value == 17:
        for card in cards:
            if cardlist[card] == 11:
                return True
    return False

# 玩家初始筹码:1个绿色($10)、5个红色($5)、10个白色($1),总计$45
playerchips = [1, 5, 10]
print("Red chips are worth $5, White chips $1, and green chips $10")

def rungame():
    global playerchips, player1cards, dealercards, dealt_cards
    
    # 重置已抽卡片列表
    dealt_cards.clear()
    
    print(f"You have {playerchips[2]} white chips, {playerchips[1]} red chips, and {playerchips[0]} green chips.")
    
    while True:
        Chipsbet = input("Type how many chips you would like to put in in the format of green, red, white. Example: 1, 2, 4 would be 1 green, 2 red, and 4 white: ")
        Chipsbet = Chipsbet.split(", ")
        if len(Chipsbet) != 3:
            print("Invalid input. Please enter the number of chips for each color.")
            continue
        try:
            bet_green, bet_red, bet_white = map(int, Chipsbet)
        except ValueError:
            print("Invalid input. Please enter numeric values.")
            continue
        if bet_green < 0 or bet_red < 0 or bet_white < 0:
            print("Invalid input. Chips cannot be negative.")
            continue
        total_bet = bet_green * 10 + bet_red * 5 + bet_white * 1
        if total_bet == 0:
            print("You need to bet at least one chip.")
            continue
        if bet_green > playerchips[0] or bet_red > playerchips[1] or bet_white > playerchips[2]:
            print("You don't have enough chips to make that bet.")
            continue
        break
    
    # 扣除下注筹码
    playerchips[0] -= bet_green
    playerchips[1] -= bet_red
    playerchips[2] -= bet_white
    total_bet = bet_green * 10 + bet_red * 5 + bet_white * 1

    # 发牌
    draw_cards()
    print(f'''
You have been dealt the cards '{player1cards[0]}' and '{player1cards[1]}'. The dealer has been dealt '{dealercards[0]}' and an unknown card.''')
    
    while True:
        hitorout = input("Would you like to 'hit' or 'stand'? ").lower()
        if hitorout == 'hit':
            dealcard = random.choice(list(cardlist.keys()))
            while dealcard in dealt_cards:
                dealcard = random.choice(list(cardlist.keys()))
            player1cards.append(dealcard)
            dealt_cards.append(dealcard)
            print(f"You have been dealt '{dealcard}'.")
            player_value = calculate_hand_value(player1cards)
            print(f"Your current hand value is {player_value}.")
            if player_value > 21:
                print("Bust! You exceeded 21.")
                break
        elif hitorout == 'stand':
            print("You chose to stand.")
            break
        else:
            print("Invalid input. Please type 'hit' or 'stand'.")

    player_value = calculate_hand_value(player1cards)
    dealer_value = calculate_hand_value(dealercards)

    while dealer_value < 17 or (dealer_value == 17 and is_soft_17(dealercards)):
        dealcard = random.choice(list(cardlist.keys()))
        while dealcard in dealt_cards:
            dealcard = random.choice(list(cardlist.keys()))
        dealercards.append(dealcard)
        dealt_cards.append(dealcard)
        dealer_value = calculate_hand_value(dealercards)
        print(f"The dealer currently has the cards:")
        for card in dealercards:
            time.sleep(1)
            print(card)
        time.sleep(1)
        print("The dealer has either hit a soft 17 or has a card value under 17. They must draw another card.")
        time.sleep(1)
        print(f"The dealer has drawn '{dealcard}'. Current dealer value: {dealer_value}")

    print("The dealer's final hand is: ")
    for card in dealercards:
        time.sleep(1)
        print(card)
    time.sleep(1.5)
    
    if player_value > 21:
        print("You busted. You lose your bet.")
    elif dealer_value > 21:
        print("The dealer busted. You win!")
        playerchips[0] += bet_green * 2
        playerchips[1] += bet_red * 2
        playerchips[2] += bet_white * 2
    elif player_value > dealer_value:
        print("You won! You get double the chips you put in.")
        playerchips[0] += bet_green * 2
        playerchips[1] += bet_red * 2
        playerchips[2] += bet_white * 2
    elif player_value < dealer_value:
        print("You lost. You lose the chips you put in.")
    else:
        print("It's a tie. Dealer wins, you lose the chips you put in.")

    print(f"Your current chip count is: {playerchips[0]} green chips, {playerchips[1]} red chips, and {playerchips[2]} white chips.")

rungame()
while True:
    runanother=input("Do you want to 'play again', or 'cash out'? ").lower()
    if runanother=='cash out':
        cash_out()
    elif runanother == 'play again':
        rungame()
    else:
        print("Invalid response.")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 08:07:03