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

扑克游戏出牌功能异常:选中卡牌与实际出牌不符问题求助

扑克游戏出牌功能索引异常问题排查与修复

开发的扑克游戏目前实现了抽7张手牌、弃牌/出牌基础功能,但出牌时索引完全混乱:

  • 请求打出手牌第4、5、6、7张时,实际打出第2、3、4、5张
  • 输入打第1张时,随机打出其他卡牌

核心功能代码(出牌/弃牌)

def phase1(deck,hand):
    InPlay = []
    DorP = input("discard or play: enter D or P:  ")

    if DorP == "D":
        discard = input("enter the cards to discard: e.g. 1267:   ")
        splitD = [int(i) - 1 for i in list(discard)]  # Convert to zero-based index
        splitD.sort(reverse=True)  # Sort indices in reverse order

        for num in splitD:
            hand.pop(num)

    if DorP == "P":
        ToPlay = input("enter the cards to play: e.g. 1267:   ")
        splitP = [int(i) - 1 for i in list(ToPlay)]  # Convert to zero-based index
        splitP.sort(reverse=True)  # Sort indices in reverse order

        for num in splitP:
            InPlay.append(hand[num])  # Add card to InPlay
            hand.pop(num)  # Remove card from deck

    
        print("\n~~~~~~~~~~~~~~~~~~~~~~")
        print("In Play:", InPlay)

完整代码

import random

deck = ["Ace spades", "2 spades", "3 spades", "4 spades", "5 spades", "6 spades", "7 spades", "8 spades", "9 spades","10 spades", "Jack spades", "Queen spades", "King spades", "Ace clubs", "2 clubs", "3 clubs", "4 clubs", "5 clubs", "6 clubs", "7 clubs", "8 clubs", "9 clubs", "10 clubs", "Jack clubs", "Queen clubs", "King clubs", "Ace hearts", "2 hearts", "3 hearts", "4 hearts", "5 hearts", "6 hearts", "7 hearts", "8 hearts", "9 hearts","10 hearts", "Jack hearts", "Queen hearts", "King hearts", "Ace diamonds", "2 diamonds", "3 diamonds", "4 diamonds","5 diamonds", "6 diamonds", "7 diamonds", "8 diamonds", "9 diamonds", "10 diamonds", "Jack diamonds", "Queen diamonds",
"King diamonds"]

InPlay = []
hand = []
stop = False

def shuffle(deck):
    temp = []
    for i in range(len(deck)):
        num = random.randint(0,len(deck)-1)
        temp.append(deck[num])
        deck.pop(num)
    for i in range(len(temp)):
        deck.append(temp[i])
    temp = []

def draw(deck,hand):
    temp = []
    nums = []
    aces = []  # To store aces separately

    # Extract the first 7 cards
    for i in range(-(len(hand)-7)):
        hand.append(deck.pop(0))  # Always pop the first card in the remaining deck
    
    for card in hand:
        rank = card.split()[0]
        if rank == "Ace":
            aces.append(card)  # Separate Aces into the aces list
        elif rank.isdigit():
            nums.append((int(rank), card))  # Store as tuple (rank, card)
        elif rank == "Jack":
            nums.append((11, card))
        elif rank == "Queen":
            nums.append((12, card))
        elif rank == "King":
            nums.append((13, card))

    # Sort the numeric cards in descending order
    nums.sort(reverse=True, key=lambda x: x[0])

    hand = []

    # Add aces first, then the sorted numeric cards
    hand.extend(aces)
    hand.extend([card for _, card in nums])

    print("hand:", hand)

def phase1(deck,hand):
    InPlay = []
    DorP = input("discard or play: enter D or P:  ")

    if DorP == "D":
        discard = input("enter the cards to discard: e.g. 1267:   ")
        splitD = [int(i) - 1 for i in list(discard)]  # Convert to zero-based index
        splitD.sort(reverse=True)  # Sort indices in reverse order

        for num in splitD:
            hand.pop(num)

    if DorP == "P":
        ToPlay = input("enter the cards to play: e.g. 1267:   ")
        splitP = [int(i) - 1 for i in list(ToPlay)]  # Convert to zero-based index
        splitP.sort(reverse=True)  # Sort indices in reverse order

        for num in splitP:
            InPlay.append(hand[num])  # Add card to InPlay
            hand.pop(num)  # Remove card from deck

    
        print("\n~~~~~~~~~~~~~~~~~~~~~~")
        print("In Play:", InPlay)
    
for i in range(0,3):
        print()
print("~~~~~~~~~~~~~~~~~~~~~~")
shuffle(deck)
draw(deck,hand)
print("~~~~~~~~~~~~~~~~~~~~~~\n")

while stop == False:
    phase1(deck,hand)
    print("~~~~~~~~~~~~~~~~~~~~~~\n")

运行示例

~~~~~~~~~~~~~~~~~~~~~~
hand: ['King clubs', '10 spades', '9 spades', '8 clubs', '7 hearts', '4 clubs', '3 spades']
~~~~~~~~~~~~~~~~~~~~~~

discard or play: enter D or P:  P
enter the cards to play: e.g. 1267:   1

~~~~~~~~~~~~~~~~~~~~~~
In Play: ['4 clubs']
~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~
hand: ['King clubs', '10 spades', '9 spades', '8 clubs', '7 hearts', '7 clubs', '3 spades']
~~~~~~~~~~~~~~~~~~~~~~
discard or play: enter D or P:  P
enter the cards to play: e.g. 1267:   1

~~~~~~~~~~~~~~~~~~~~~~
In Play: ['3 spades']
~~~~~~~~~~~~~~~~~~~~~~

问题原因

核心bug出在draw函数中:
当执行hand = []时,是在函数内部创建了一个新的局部列表变量,而非修改传入的全局hand列表。后续排序后的卡牌都添加到了这个局部hand里,打印的也是这个局部列表,但全局的hand仍然是抽牌后未排序的原始列表。

用户看到的是排序后的手牌,但phase1操作的却是未排序的全局hand,两者索引完全不匹配,导致出牌时选的索引对应到错误卡牌。


修复方法

修改draw函数,不要重新赋值hand,而是清空原列表后添加排序后的元素,确保操作的是同一个列表引用:

def draw(deck,hand):
    temp = []
    nums = []
    aces = []  # To store aces separately

    # Extract the first 7 cards
    for i in range(-(len(hand)-7)):
        hand.append(deck.pop(0))  # Always pop the first card in the remaining deck
    
    for card in hand:
        rank = card.split()[0]
        if rank == "Ace":
            aces.append(card)  # Separate Aces into the aces list
        elif rank.isdigit():
            nums.append((int(rank), card))  # Store as tuple (rank, card)
        elif rank == "Jack":
            nums.append((11, card))
        elif rank == "Queen":
            nums.append((12, card))
        elif rank == "King":
            nums.append((13, card))

    # Sort the numeric cards in descending order
    nums.sort(reverse=True, key=lambda x: x[0])

    # 清空原hand列表,而非创建新列表
    hand.clear()
    # 添加排序后的卡牌
    hand.extend(aces)
    hand.extend([card for _, card in nums])

    print("hand:", hand)

额外优化建议

  • 在phase1中先打印当前手牌,避免用户记忆之前的手牌内容
  • 增加输入验证:检查用户输入的牌号是否在有效范围内(1到当前手牌长度),防止索引越界错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:00:57