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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:24:15