Python Blackjack玩家类开发:如何调用Deck类方法抽取卡牌
Python 二十一点游戏:完善Player类实现从Deck取牌
核心问题说明
你完全可以跨类调用方法,但关键是Player类需要持有具体Deck实例的引用——因为deal_card是Deck的实例方法,必须通过已经创建好的Deck对象来调用,而不是直接调用类本身。另外你的Deck类目前把deck定义为类属性,会导致所有Deck实例共享同一个牌堆,这是不合理的,需要先修正这个问题。
具体解决方案
1. 修复Deck类的牌堆属性
把类级别的deck = []移到__init__方法里作为实例属性,确保每个Deck实例有独立的牌堆:
class Deck: def __init__(self): self.deck = [] # 改为实例属性 suits = "Hearts", "Diamonds", "Clubs", "Spades" ranks = 2,3,4,5,6,7,8,9,10,"J","Q","K","A" for suit in suits: for rank in ranks: card= Card(rank,suit) self.deck.append(card) # 其他方法保持不变
2. 完善Player类的draw_cards方法
让draw_cards接收一个Deck实例作为参数,调用其deal_card方法获取卡牌,再添加到玩家手牌:
class Player: def __init__(self, name, isdealer): self.name = name self.hand = [] self.isdealer = isdealer def draw_cards(self, deck): # 从传入的Deck实例取牌,添加到手牌 card = deck.deal_card() self.hand.append(card) # 可选:打印取牌信息,方便调试 print(f"{self.name} drew: {card}")
3. 在主逻辑中完成交互
在main函数里创建Deck和Player实例后,调用draw_cards时传入Deck对象即可:
def main(): # 欢迎语和规则保持不变 print("""Welcome to Blackjack! Here are the Rules Try to get as close to 21 without going over. Kings, Queens, and Jacks are worth 10 points. Aces are worth 1 or 11 points. Cards 2 through 10 are worth their face value. (H)it to take another card. (S)tand to stop taking cards. The dealer stops hitting at 17""") # 创建洗牌后的牌堆 deck = Deck() deck.shuffle() # 创建玩家和庄家 player = Player("Player 1", isdealer=False) dealer = Player("Dealer", isdealer=True) # 初始发牌(每人2张) for _ in range(2): player.draw_cards(deck) dealer.draw_cards(deck) # 打印玩家手牌示例 print(f"\n{player.name}'s hand:") for card in player.hand: print(card) print(f"\n{dealer.name}'s hand:") print(dealer.hand[0]) # 庄家隐藏第二张牌,符合规则 print("Hidden card")
补充说明
如果你希望Player实例长期关联同一个Deck(比如整局游戏用同一个牌堆),也可以在Player初始化时传入Deck实例并保存为属性:
class Player: def __init__(self, name, isdealer, deck): self.name = name self.hand = [] self.isdealer = isdealer self.deck = deck # 保存Deck实例引用 def draw_cards(self): card = self.deck.deal_card() self.hand.append(card)
这种方式下,创建Player时直接传入deck即可:player = Player("Player 1", False, deck),后续调用draw_cards不需要再传参数。
内容的提问来源于stack exchange,提问作者user17598401
相关产品推荐
相关产品推荐

