Blackjack游戏触发RecursionError:递归深度超出问题求助
解决Blackjack游戏中的RecursionError问题
错误根源分析
看回溯信息就能发现,问题根本不在random.shuffle(),而是Dealer类的无限递归实例化:
def __init__(self, player_name): self._hand = [] self._deck = Deck() self._player = Player(player_name) self._dealer = Dealer('Dealer') # 这里是罪魁祸首!
每次创建Dealer对象时,构造函数里都会再创建一个新的Dealer实例,这个新实例又会重复执行同样的逻辑,无限循环下去,直到触发Python的递归深度限制,抛出RecursionError。报错点落在random.shuffle()只是因为递归过程中多次调用了Deck的populate方法,属于连锁反应。
修复方案
1. 重构Dealer类的设计
Dealer本质上也是一个玩家,没必要自己实例化自己,直接复用Player类即可:
class Dealer: def __init__(self, player_name): self._deck = Deck() self._player = Player(player_name) self._dealer_player = Player('Dealer') # 用Player实例表示庄家
之后把所有原来用到self._dealer的地方,全部替换成self._dealer_player,比如发牌、计算分数的逻辑。
2. 修复Player类的变量错误
Player的get_score方法里有个笔误,把score写成了value:
# 错误代码 while aces > 0 and score > 21: value -= 10 aces -= 1 # 修正后 while aces > 0 and score > 21: score -= 10 aces -= 1
3. 移除冗余测试代码
代码开头的Deck测试会在游戏启动前就执行,影响正常流程,建议注释或删除:
#Test my_deck = Deck() print(my_deck)
修复后的完整代码
import random class Card: def __init__(self, suit, number): self._suit = suit self._number = number def __repr__(self): return self._number + ' of ' + self._suit @property def suit(self): return self._suit @suit.setter def suit(self, suit): if suit in ['Hearts', 'Clubs', 'Diamonds', 'Spades']: self._suit = suit else: print("That's not a valid suit") @property def number(self): return self._number @number.setter def number(self, number): if number in ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']: self._number = number else: print("That's not a valid number") class Deck: def __init__(self): self._cards = [] self.populate() def __repr__(self) -> str: return f'{self._cards}' def populate(self): suits = ['Hearts', 'Clubs', 'Diamonds', 'Spades'] numbers = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] cards = [] for suit in suits: for number in numbers: cards.append(Card(suit, number)) self._cards = cards random.shuffle(self._cards) class Player: def __init__(self, name, hand=None, score=0): self._name = name self._hand = [] if hand is None else hand self._score = score def add_card(self, card): self._hand.append(card) def get_score(self): score = 0 aces = 0 for card in self._hand: if card.number == 'A': aces += 1 score += 11 elif card.number in ['J', 'Q', 'K']: score += 10 else: score += int(card.number) while aces > 0 and score > 21: score -= 10 aces -= 1 return score class Dealer: def __init__(self, player_name): self._deck = Deck() self._player = Player(player_name) self._dealer_player = Player('Dealer') def first_cards(self): self._player.add_card(self._deck._cards.pop()) self._dealer_player.add_card(self._deck._cards.pop()) self._player.add_card(self._deck._cards.pop()) self._dealer_player.add_card(self._deck._cards.pop()) def player_turn(self): while self._player.get_score() < 21: choice = str(input('Do you want to hit? (Y/N)')).lower() if choice == 'y': self._player.add_card(self._deck._cards.pop()) print(f'Your current score is : {self._player.get_score()}') else: break def dealer_turn(self): while self._dealer_player.get_score() < 17: self._dealer_player.add_card(self._deck._cards.pop()) print(f'The dealer\'s score is: {self._dealer_player.get_score()}') def start(self): print('Welcome to blackjack! By Nils Edstrom') self.first_cards() # 庄家初始只显示一张牌的分数,更符合真实规则 dealer_visible_score = self._dealer_player._hand[1].number dealer_visible_score = 11 if dealer_visible_score == 'A' else 10 if dealer_visible_score in ['J','Q','K'] else int(dealer_visible_score) print(f'Your current score is: {self._player.get_score()}') print(f'The dealer\'s visible score is: {dealer_visible_score}') self.player_turn() if self._player.get_score() > 21: print(f'You lose! Your current score is: {self._player.get_score()}') return self.dealer_turn() if self._dealer_player.get_score() > 21: print('You won! Dealer busted.') elif self._player.get_score() > self._dealer_player.get_score(): print('You won!') elif self._player.get_score() < self._dealer_player.get_score(): print('The dealer won!') else: print('It\'s a tie!') player1 = str(input('What is your name? ')) dealer = Dealer(player1) dealer.start()
内容的提问来源于stack exchange,提问作者Nils Edström
相关产品推荐
相关产品推荐

