Python Blackjack游戏end_game函数返回值及逻辑问题咨询
二十一点(Blackjack)游戏end_game函数实现优化
我正在用Python编写二十一点游戏,目前卡在end_game函数的实现上。这个函数需要判断玩家和对手的胜负,但我不确定该返回什么内容。我设置了循环询问玩家是否要额外卡牌,同时需要验证玩家手牌是否爆牌,并在游戏结束时判定胜负,相关代码如下:
import random from art import logo cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10] player_deck = [] opponent_deck = [] def table(): """Table of cards for each player.""" print(f" Your cards: {player_deck}, current score: {sum(player_deck)}") print(f" Computer's first card: {opponent_deck[0]}") def add_card(player: list): """Add a new card on the current deck.""" player.append(random.choice(cards)) def deck(player: list): """Define the deck for a player, need to define the first argument as a list.""" for x in range(0,2): add_card(player) # Verify if the player just passed the number of cards necessary to play again. def opponent_win(): print(f" Your final hand: {player_deck}, final score: {sum(player_deck)}") print(f" Computer's final hand: {opponent_deck}, final score: {sum(opponent_deck)}") print("You went over. You lose =(") def player_win(): print(f" Your final hand: {player_deck}, final score: {sum(player_deck)}") print(f" The computer's final hand: {opponent_deck}, final score: {sum(opponent_deck)}") print("Opponent went over. You win =)") # End Game def end_game(player_decision): """Tell if the player or the opponent win""" sum_player = sum(player_deck) sum_opponent = sum(opponent_deck) if sum_player == sum_opponent: return print("Drawn") elif sum_player == 21: return player_win() elif sum_player > 21: return opponent_win() elif sum_opponent > 21: return player_win() elif sum_opponent == 21: return opponent_win() if player_decision == "y": add_card(player_deck) if sum_opponent > sum_player: return opponent_win() elif sum_player > sum_opponent: return player_win() def start(): """Start the blackjack game.""" # Show the logo print(logo) print("\n" * 50) # Set your deck and the opponent deck and start the table deck(player_deck) deck(opponent_deck) while sum(opponent_deck) < 21: add_card(opponent_deck) table() while True: another_card = input("Type 'y' to get another card, type 'n' to pass: ").lower() end_game(another_card) while True: confirm = input("Do you want to play a game of blackjack? (y/n): ") if confirm != "n": start() player_deck = [] opponent_deck = [] else: break
问题分析与修复方案
原代码存在几个关键逻辑问题,导致end_game函数无法正常工作:
- 对手补牌逻辑错误:原代码中对手会一直补牌直到分数≥21,不符合二十一点规则(对手通常在分数<17时才补牌)
- end_game职责混乱:把玩家补牌操作和胜负判断混在一起,游戏流程逻辑混乱
- 缺少Ace牌转换逻辑:当玩家手牌包含11(Ace)且总分超过21时,未将11转为1,会误判爆牌
- 游戏循环未正确终止:玩家选择不补牌或爆牌后,循环没有终止,会一直重复询问
修改后的完整代码
import random from art import logo cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10] player_deck = [] opponent_deck = [] def adjust_ace(deck): """调整Ace牌的数值,当总分超过21时将11转为1""" while sum(deck) > 21 and 11 in deck: deck[deck.index(11)] = 1 def table(): """显示双方手牌信息""" print(f" Your cards: {player_deck}, current score: {sum(player_deck)}") print(f" Computer's first card: {opponent_deck[0]}") def add_card(player: list): """给指定玩家添加一张随机卡牌""" player.append(random.choice(cards)) adjust_ace(player) def deck(player: list): """初始化玩家手牌(两张牌)""" for _ in range(2): add_card(player) def show_final_result(): """显示最终手牌和分数""" print(f" Your final hand: {player_deck}, final score: {sum(player_deck)}") print(f" Computer's final hand: {opponent_deck}, final score: {sum(opponent_deck)}") def opponent_win(): show_final_result() print("You lose =(") def player_win(): show_final_result() print("You win =)") def draw_game(): show_final_result() print("It's a draw!") # End Game def end_game(): """判定游戏胜负并结束游戏""" sum_player = sum(player_deck) sum_opponent = sum(opponent_deck) # 处理对手补牌逻辑(遵循规则:分数<17时补牌) while sum_opponent < 17: add_card(opponent_deck) sum_opponent = sum(opponent_deck) # 胜负判定逻辑 if sum_player > 21: opponent_win() elif sum_opponent > 21: player_win() elif sum_player == 21 and len(player_deck) == 2: # 玩家黑杰克(两张牌凑21) player_win() elif sum_opponent == 21 and len(opponent_deck) == 2: # 对手黑杰克 opponent_win() elif sum_player == sum_opponent: draw_game() elif sum_player > sum_opponent: player_win() else: opponent_win() def start(): """启动游戏""" print(logo) print("\n" * 50) # 初始化手牌 deck(player_deck) deck(opponent_deck) table() # 玩家回合循环 while True: sum_player = sum(player_deck) if sum_player >= 21: break another_card = input("Type 'y' to get another card, type 'n' to pass: ").lower() if another_card == "y": add_card(player_deck) table() else: break # 进入胜负判定 end_game() while True: confirm = input("Do you want to play a game of blackjack? (y/n): ").lower() if confirm == "y": start() # 重置手牌 player_deck = [] opponent_deck = [] else: print("Thanks for playing!") break
关键改动说明
- 新增Ace牌调整函数:
adjust_ace会在玩家/对手总分超过21时,将手牌中的11转为1,避免不合理的爆牌判定 - 拆分end_game职责:
end_game不再处理玩家补牌,专注于对手补牌和胜负判定,逻辑更清晰 - 修正对手补牌规则:对手仅在分数<17时补牌,符合标准二十一点规则
- 优化游戏循环:玩家回合在爆牌、拿到21或选择不补牌时终止,随后触发胜负判定
- 补充黑杰克判定:专门处理两张牌凑21的黑杰克情况,优先级高于普通胜负判定
内容的提问来源于stack exchange,提问作者CRY WHY
相关产品推荐
相关产品推荐

