如何修改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
相关产品推荐
相关产品推荐

