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

如何修改Python抽卡程序以避免重复抽卡?

问题描述

现有一段Python随机抽卡程序,能随机生成卡牌并输出,但需要实现记录已抽取卡牌、防止重复抽卡的功能。考虑过用set()、remove()或pop()方法,但不确定具体实现方式,寻求帮助。

原代码如下:

#Imports random method
import random

#Gets the value of the card
def getCard():
    global cards,cardSelect
    #List of possible cards in an array
    cards = ["Ace",2,3,4,5,6,7,8,9,10,"Jack","Queen","King"]
    #Selects a card
    cardSelect = random.choice(cards)

#Gets the suit of the card 
def getSuit():
    global suits,suitSelect
    #List of possible suits in an array
    suits = ["Hearts","Spades","Clubs","Diamonds"]
        #Selects a suit
    suitSelect = random.choice(suits)

#Prints the cards
def buildCard():
    global cards,suits,cardSelect,suitSelect

    #Calls other functions
    getCard()
    getSuit()

    #Chooses color randomly
    color = random.randint(1,2)
    #Defines randomly selected value to the name of a color : Red or Black
    if color == 1:
        color = "Red"
    if color == 2:
        color = "Black"

    #Prints every card in a 52 deck
    print("You drew a",color,cardSelect,"of",suitSelect)

#Calls BuildCard
while True:
    input()
    buildCard()
解决方案

方法一:预构建完整牌组,抽卡后移除已抽卡牌

核心思路是先生成全部52张牌存入列表,每次抽卡时随机选取一张,再从牌组中移除该卡牌,同时用列表记录已抽卡牌。这种方式逻辑直观,适合新手理解。

修改后的代码:

import random

# 初始化完整牌组和已抽卡牌记录
def init_deck():
    global deck, drawn_cards
    ranks = ["Ace",2,3,4,5,6,7,8,9,10,"Jack","Queen","King"]
    suits = ["Hearts","Spades","Clubs","Diamonds"]
    # 生成所有52张牌,每张牌用元组(rank, suit, color)表示
    deck = []
    for rank in ranks:
        for suit in suits:
            # 修正原代码的颜色随机错误:红桃、方块为红色,黑桃、梅花为黑色
            color = "Red" if suit in ["Hearts", "Diamonds"] else "Black"
            deck.append( (rank, suit, color) )
    drawn_cards = []

# 抽卡函数
def draw_card():
    global deck, drawn_cards
    if not deck:
        print("牌组已经抽完了!")
        return None
    # 随机选一张牌
    selected_card = random.choice(deck)
    # 从牌组移除已选卡牌
    deck.remove(selected_card)
    # 记录已抽卡牌
    drawn_cards.append(selected_card)
    return selected_card

# 主循环
init_deck()
while True:
    input("按回车键抽卡...")
    card = draw_card()
    if card:
        rank, suit, color = card
        print(f"You drew a {color} {rank} of {suit}")
    else:
        break

方法二:打乱牌组后逐个弹出(更高效)

如果牌组规模大,random.choice()加remove()的效率较低(列表移除元素需移动后续元素),可以先打乱牌组,再用pop()从列表末尾取牌,操作更高效。

修改后的代码:

import random

def init_deck():
    global deck, drawn_cards
    ranks = ["Ace",2,3,4,5,6,7,8,9,10,"Jack","Queen","King"]
    suits = ["Hearts","Spades","Clubs","Diamonds"]
    deck = []
    for rank in ranks:
        for suit in suits:
            color = "Red" if suit in ["Hearts", "Diamonds"] else "Black"
            deck.append( (rank, suit, color) )
    # 打乱牌组顺序
    random.shuffle(deck)
    drawn_cards = []

def draw_card():
    global deck, drawn_cards
    if not deck:
        print("牌组已经抽完了!")
        return None
    # 从牌组末尾弹出一张牌
    selected_card = deck.pop()
    drawn_cards.append(selected_card)
    return selected_card

init_deck()
while True:
    input("按回车键抽卡...")
    card = draw_card()
    if card:
        rank, suit, color = card
        print(f"You drew a {color} {rank} of {suit}")
    else:
        break

补充说明

  • 原代码中随机选择颜色的逻辑错误,卡牌颜色由花色决定,已在修改后的代码中修正。
  • drawn_cards列表用于记录抽卡顺序,若只需记录已抽卡牌无需顺序,可改用set():将drawn_cards = []改为drawn_cards = set(),添加时用drawn_cards.add(selected_card)即可。
  • 若要查看已抽卡牌历史,直接打印drawn_cards即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 03:35:27