循环在第三次迭代开始时结束

编程语言 2026-07-09

你好,正在阅读这段话的你,我现在在调试我的代码,卡在一个奇怪的错误上。

我为这个项目使用了两个主要文件,一个叫做 logic.py,一个叫做 card.py。整个游戏循环依赖两个变量为真,match_goingPlayerTurn。我在继续游戏提示中确保把这些值设为True,但在程序的第三次循环时,它会执行 startMatch(),然后结束程序。

请见下方的期望结果。我在GitHub上的代码位于bin文件夹,可以在此处查看 这里。此外,还有一个Pastebin链接在这里 --> https://paste.pythondiscord.com/7RKQ 我今晚可以上传一个调试器输出的视频。我已经把导致问题的主要代码放在下面,我完全知道 我的游戏循环代码真的很不规范。我想知道为什么我的代码不会返回到while循环,

#This code is ran before the code above 
while match_going and PlayerTurn:
    # Grab input inside the loop so it asks every time
    player_input = input("Stand or Hit:\n").lower()

    if player_input == "hit":
        deck.draw_card(Player_Hand,"Player")
        player_score = deck.ScoreCard(Player_Hand)
        print("Player's Hand Score Currently:\n", player_score)

            # Check if they busted
        if player_score > 21:
                print("Past 21! You busted...")
                PlayerTurn = False
                match_going = False


    elif player_input == "stand":
        PlayerTurn = False
        print("**Dealer's Turn**")
        deck.draw_card(Dealer_Hand,"Dealer")
        dealer_score = deck.ScoreCard(Dealer_Hand)
        # Dealer must hit until they beat 16 or land on 16
        while dealer_score < 16:
            deck.draw_card(Dealer_Hand,"Dealer")
            dealer_score = deck.ScoreCard(Dealer_Hand)
            if dealer_score == 16 and player_score > dealer_score:
                print("You win!")
                match_going = endMatch()
                WinCounter += 1
            if dealer_score == 16 and dealer_score > player_score:
                print("Dealer Wins!")
                match_going = endMatch()
            if dealer_score >= player_score and dealer_score <= 21:
                print("Dealer wins!")
                match_going = endMatch()
            elif dealer_score < player_score and player_score <= 21:
                print("You win!")
                match_going = endMatch()
                WinCounter += 1
            elif dealer_score > 21:
                print("Dealer bust you win!")
                match_going = endMatch()
                WinCounter += 1
            elif dealer_score == player_score:
                print("Match was a draw!")
                match_going = endMatch() # Ends game loop
print("Current Win Streak:",WinCounter)
user_continue_match = str(input("\nContinue Playing? Y/N").upper())
if user_continue_match == "Y":
    reset()
    match_going = True
    PlayerTurn = True
    startMatch()
    player_score = deck.ScoreCard(Player_Hand)
    dealer_score = deck.ScoreCard(Dealer_Hand) 
if user_continue_match == "N":
    print("Your Are Safe To Close Program")
#This runs in the same file after match_going & PlayerTurn has been set to false

预期结果:
程序应一直运行,直到用户输入“ N ”。也就是说,程序会不断返回到logic.py第 53行所在的while循环。

实际情况:
程序提前结束,在执行完第103行的if语句后不会跳回到第53行。

如果有人能提供帮助那就太好了。我在Python Discord请求帮助,结果却得到了一些让人困惑的回复。

解决方案

我运行了你的代码,发现了两个问题:

  1. 如果你在文件 logic.py 的开头放入类似 print('run logic.py') 的内容,你会看到它会执行两次。这很奇怪。但我发现问题出在在 logic.py 处你运行了 deck.draw_card(...),它包含第 import logic as Logic 行,这会让 logic.py 第二次执行——循环会执行两次,但本应只执行一次(这是第二个错误)。即使你为 Continue Playing 选择了 N,它也会再次运行。

如果你把card.py中的两个位置的所有 import logic as Logic 去掉,这个问题就解决了。坦率地说,你在 card 里其实并不需要这个 logic

顺便说一句:一个很好的规则是在文件开头放置所有的 import,这样有助于看清这个文件还使用了哪些其他模块。

  1. 第二个问题是你的 while 循环和 Continue Playing——它应该只执行一次,因为你需要把它放到另一个/外部的 while 循环中(例如 while True),并在用户为 Continue Playing 选择 N 时使用 break 来退出它。
# --- external loop
while True:

   # -- inner loop
   while match_going and PlayerTurn:

       # ... code ...

   # --- after inner loop
   user_continue_match = input("\nContinue Playing? Y/N").upper()

   if user_continue_match == "Y":
       # ... code ...
   else:
       break  # exit external loop

最终你也可以为此再使用一个变量

# --- before external loop
running = True

# --- external loop
while running:

   # --- inner loop
   while match_going and PlayerTurn:

       # ... code ...

   # --- after inner loop
   user_continue_match = input("\nContinue Playing? Y/N").upper()

   if user_continue_match == "Y":
       # ... code ...
   else:
       running = False # exit external loop

用于测试的完整可运行代码(包含其他改动):

我使用了 Linux,因此为Linux终端添加了颜色代码。

logic.py

# -----

import platform

# colors for linux terminal
COLOR = (platform.system() == 'Linux')
C_R = "\033[31;1m"  # red bold/bright
C_G = "\033[32;1m"  # green bold/bright
C_X = "\033[m"  # reset


def debug(text):
    if COLOR:
        print(f"{C_R}[DEBUG]: {text}{C_X}")
    else:
        print(f"[DEBUG]: {text}")

# -----

debug("run logic.py")

import random
import card as deck

# --- functions ---


def reset():  # NOTE: Purpose of this function is to reset values that need to be used in the next loop
    debug("reset")

    player_hand.clear()
    dealer_hand.clear()

    total_hand_score = 0
    dealer_score = 0
    dealer_score = 0
    player_score = 0

    return (
        player_hand,
        dealer_hand,
        total_hand_score,
        dealer_score,
        dealer_score,
        player_score,
    )


def start_match():
    debug("start_match")

    deck.draw_card(player_hand, "Player")
    deck.draw_card(player_hand, "Player")

    deck.draw_card(dealer_hand, "Dealer")

    print("Current Dealer Hand \n", dealer_hand)
    print("Current Player Hand\n", player_hand)

    return True


def end_match():
    debug("end_match")

    return False


# --- main ---

# Functions to be called throughout the game multiple times#
# deck.draw_card((hand you are giving the card to), "Text you want to print out")
# deck.score_card((hand you are scoring aka dealer_hand or player_hand))

# Variables
player_hand = []
dealer_hand = []

match_going = True
player_turn = True
total_hand_score = 0
dealer_score = 0

running = True

while running:
    debug("run external loop")

    start_match()
    dealer_score = deck.score_card(dealer_hand)
    player_score = deck.score_card(player_hand)

    print("Dealer's Hand Score:\n", dealer_score)
    print("Player's Hand Score:\n", player_score)

    while match_going and player_turn:
        debug("run inner loop")

        # Grab input inside the loop so it asks every time
        player_input = input("[S]tand or [H]it:\n").lower()

        if player_input in ("hit", "h"):  # I prefer single `h` instead of `hit`
            deck.draw_card(player_hand, "Player")
            player_score = deck.score_card(player_hand)
            print("Player's Hand Score Currently:\n", player_score)

            # Check if they busted
            if player_score > 21:
                print("Past 21! You busted...")
                player_turn = False
                match_going = False

        elif player_input in ("stand", "s"):  # I prefer single `s` instead of `stand`
            player_turn = False
            print("**Dealer's Turn**")
            deck.draw_card(dealer_hand, "Dealer")
            dealer_score = deck.score_card(dealer_hand)
            # Dealer must hit until they beat 16

            while dealer_score <= 16:
                deck.draw_card(dealer_hand, "Dealer")
                dealer_score = deck.score_card(dealer_hand)

                if dealer_score >= player_score and dealer_score <= 21:
                    print("Dealer wins!")
                    match_going = end_match()
                elif dealer_score < player_score and player_score <= 21:
                    print("You win!")
                    match_going = end_match()
                elif dealer_score > 21:
                    print("Dealer bust you win!")
                    match_going = end_match()

        if dealer_score == player_score:
            print("Match was a draw!")
            match_going = end_match()  # Ends game loop

    # --- after inner loop

    debug("after inner loop")

    user_continue_match = input("Continue Playing? Y/N").upper()

    if user_continue_match == "Y":

        (
            player_hand,
            dealer_hand,
            total_hand_score,
            dealer_score,
            dealer_score,
            player_score,
        ) = reset()
        match_going = True
        player_turn = True

    elif user_continue_match == "N":
        running = False  # exit external loop and exit program

# --- after external loop

print("Your Are Safe To Close Program")
debug("end of file")

card.py

import random

card_faces = ["King", "Queen", "Jack"]
card_types = ["Spades", "Diamonds", "Hearts", "Clubs"]
card_numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


# def withdrawl(hand):  # send `player_hand` as parameter, don't use global variable
#    hand.clear()


# def deal(cards_wanted, hand, player_hand, dealer_hand):
#
#     for cards_needed in range(cards_wanted):
#
#         if hand[0] == dealer_hand[0]:
#             print("Drawing For Dealer")
#             draw_card(dealer_hand, "Dealer")
#         if hand == player_hand:
#             draw_card(player_hand, "Player")
#
#     return hand


def draw_card(hand, user_name):
    # TODO: create list with all_cards, random.shuffle(all_card), and get cards from all_cards - to make sure cards are unique

    drawn_type = random.choice(card_types)

    probe = random.uniform(0, 1)

    if probe <= 0.23:
        drawn_face = random.choice(card_faces)
        drawn_card = f"{drawn_face} of {drawn_type}"
    else:
        drawn_number = random.choice(card_numbers)
        if drawn_number == 1:
            drawn_number = "Ace"
        drawn_card = f"{drawn_number} of {drawn_type}"

    hand.append(drawn_card)

    print(user_name, "has drawn a: \n", drawn_card)

    return drawn_card, hand


def score_card(hand):

    total_hand_score = 0

    for current_card in hand:
        first_char = current_card[0]

        if first_char in ["2", "3", "4", "5", "6", "7", "8", "9"]:
            total_hand_score += int(first_char)

        elif first_char in ["1", "K", "Q", "J"]:  # `1` instead of `10`
            total_hand_score += 10

        elif first_char in ["A"]:
            total_hand_score += 0

        else:
            print("unknown card:", current_card)

    return total_hand_score
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章