如果、Elif、混淆

-1 投票
6 回答
5030 浏览
提问于 2025-04-17 17:16

在写一个二十一点游戏的脚本时,我对如何使用'if'、'elif'和'else'语句感到有些困惑。我看了很多相关的帖子,也在网上搜索过,但还是搞不清楚……我了解到,如果用'elif'代替重复的'if'语句,当某个'elif'语句为真时,代码会短路,不再检查后面的条件。这让我更加困惑(虽然我明白使用'elif'和短路的概念)。前面5个'if'语句就说明了这一点。如果我用'elif'而不是'if',那么如果玩家和庄家都得了21点,代码可能就不会检查最后一个条件……不过在这之后,我觉得我可以用'elif'语句,或者就这样保持不变……所以,我的问题是,我在main()的其他部分使用它们是否正确?如果不对,你会怎么做?非常感谢。

# current working version - - - 02/26/2013
# Notes: Nees to fix Ace problem. Ace can be 11 or 1.

import random
import os

def main():
    print "Welcome To Python Blackjack. [H] Is For A Hit, [S] Is To Stand, [Q] To       Quit.\n"
    c = ""    # Hit, Stand or Quit Variable.
    player = deal_cards()    # deal player
    dealer = deal_cards()    # deal dealer
    print "< ---- Player Hand ---->"
    print "Player Hand: ", player    
    print "Total Player Hand: ", total_hand(player)    
    print
    print "< ---- Dealer Hand ---->"
    print "Dealer Hand: ", dealer                      
    print "Total Dealer Hand: ", total_hand(dealer)
    print

    if (total_hand(player) == 21):
        print "BLACKJACK! YOU WIN!"
        message()
    if (total_hand(player) > 21):
        print "BUSTED! You Lose"
        message()
    if (total_hand(dealer) == 21):
        print "BLACKJACK! Sorry You Lose! Dealer Wins"               # must use if   statements because elif would fail to reach the tie line.
        message()
    if (total_hand(dealer) > 21):
        print "Dealer Busted! You Win!"
        message()
    if (total_hand(player) == 21) and (total_hand(dealer) == 21):    # must use if       statements because elif would fail to reach this line.
        print "Player And Dealer Tie! Game Goes To Dealer"
        message()

    while (c != "q"):   
        c = raw_input("[H]it [S]tand [Q]uit: ").lower()    
        if (c == "h"):
            hit(player)         
            print ""
            print "Your Cards Are Now: ",player                 
            print "Total For Player Is: ",total_hand(player)
            if (total_hand(player) == 21):
            print "BLACKJACK! You Win!"
            message()
            if (total_hand(player) > 21):
                print "BUSTED! Sorry, You Lose."
                message()
            if (total_hand(dealer) == 21):
                print "BLACKJACK! Sorry You Lose! Dealer Wins."
                message()
            if (total_hand(dealer) > 21):
                print "Dealer Busted! You Win!\n"
                message()
            if (total_hand(dealer) <= 17): 
                hit(dealer)
                print "\nThe Dealer Takes A Card", dealer
                print "For A Total Of: ", total_hand(dealer)
                if (total_hand(dealer) == 21):
                    print "BLACKJACK! Sorry You Lose! Dealer Wins.\n"
                    message()
                if (total_hand(dealer) > 21):
                    print "Dealer Busted! You Win!\n"
                    message()               
            elif (c == "s"):
            if (total_hand(dealer) <= 17):
                hit(dealer)
                print "The Dealer Takes A Card", dealer
                print "For A Total Of: ", total_hand(dealer)
                if (total_hand(dealer) == 21):
                    print "BLACKJACK! Dealer Wins.\n"
                    message()
                if (total_hand(dealer) > 21):
                    print "Dealer Busted! You Win!\n"
                    message()
                if (total_hand(dealer) >= total_hand(player)):
                    print "Sorry, You Lose. Dealer Wins With A Tie\n"
                    message()
                if (total_hand(player) > total_hand(dealer)):
                    print "You Win With The Best Hand!\n"
                    message()
             if (total_hand(player) > total_hand(dealer)):
                print "You Win With The Best Hand!\n"
                message()
            if (total_hand(dealer) > total_hand(player)):
                print "Sorry, You Lose. Dealer Wins\n"
                message()
        else:
            if (c == "q"):
                message()
            else:
                print "Invalid Choice. . .To Quit, Press [Q]"




def deal_cards():
    random1 = random.randint(1,11)
    random2 = random.randint(1,11)
    hand = [random1, random2]
    return hand


def hit(hand):
    newCard = random.randint(1,11)
    hand.append(newCard)
    return hand


def total_hand(hand):
    total = sum(hand)
    return total


def message():
    again = raw_input("Do You Want To Play Again? [Y] For Yes - Press Any Key To Quit:   ").lower()
    if "y" in again:
        main()
    else:
        print "Thanks For Playing"
        os._exit(1)


# main

if __name__ == '__main__':
    main()

6 个回答

1

在这种情况下,使用 elif 是完全安全的。

如果你希望多个条件中只执行 一个,那就应该使用 elif。如果有可能会有多个不相关的条件同时发生,那就用 if

下面是一个例子,说明为什么要注意这两者之间的区别:

x = 0
if x < 1:
    do_something()
elif x < 2:
    do_something_else_instead()

这种嵌套有时用来检查 x 是否在不同的范围内。不过,如果你在这里不使用 elif

x = 0
if x < 1:
    do_something()
if x < 2:
    do_something_else_instead()

那么这两个条件都会被执行,而不是只执行一个,因为如果 x 小于 1,它也一定会小于 2。这种情况有时可以通过正确的检查来避免,比如这样:

x = 0
if x < 1:
    do_something()
if x >= 1 and x < 2:
    do_something_else_instead()

但是,如果 do_something() 也修改了 x,那么它可能会增加 x 的值,使其落入 1 <= x < 2 的范围,这样第二个条件也会被执行。为了避免这个问题,只需使用 elif,这样可以确保只执行一个条件,也就是第一个返回 True 的条件。

1

如果你把代码改成在 main 里面用一个 while 循环,而不是从 message 调用 main,我觉得你的程序会变得更短、更清晰。

结构化编程 是一个曾经有争议但现在不再争论的观点,它提倡使用像 ifelif 这样的条件语句,以及像 while 这样的循环,来控制程序的执行流程,而不是使用其他方法。你从 message 调用 mainos.exit 的方式,实际上是采用了不同于结构化编程的策略。通过在 message 中反复调用 main,你会让自己陷入困境。实际上,os.exit 是为数不多的几种逃出这个困境的方法之一。另一个方法是抛出一个异常,然后在 main 外部捕获它。

所以试着这样来规划你的代码:

def main():
    play()

def play():
    again = True
    while again:
        player = deal_cards()
        dealer = deal_cards()
        print ...
        ...
        game_over = False
        while not game_over
            if (total_hand(player) == 21) and (total_hand(dealer) == 21):
                print "Player And Dealer Tie! Game Goes To Dealer"
                game_over = True
                # You don't need to do anything else here.
            elif total_hand(player) == 21:
                print ...
                game_over = True
            elif total_hand(dealer) == 21:
                print ...
                game_over = True
            elif ...
                print ...
            elif ...
                ...
            else ...
                print ...

            if not game_over:
                c = raw_input("[H]it [S]tand [Q]uit: ").lower()
                if c == "q":
                    game_over = True
                elif c == "h":
                    hit(player)
                    # You don't need to do anything else here.
                else:
                    ...

        answer = raw_input("Do You Want To Play Again? [Y] For Yes - Press Any Key To Quit:   ").lower()
        again = ("y" in answer)

(请忽略这条给专家的备注,因为这里有很多专家在 Stack Overflow:我知道有一些有趣的替代结构化编程的方法,比如递归、适当的尾调用和跳板技术。但对于这个特定的问题,我认为这些不是下一步。)

2

试着把更具体的条件放在不那么具体的条件前面。

比如说,如果你把顺序从这个

if (total_hand(player) == 21):
    print "BLACKJACK! YOU WIN!"
    message()
if (total_hand(player) > 21):
    print "BUSTED! You Lose"
    message()
if (total_hand(dealer) == 21):
    print "BLACKJACK! Sorry You Lose! Dealer Wins"                
    message()
if (total_hand(dealer) > 21):
    print "Dealer Busted! You Win!"
    message()
if (total_hand(player) == 21) and (total_hand(dealer) == 21):         
    print "Player And Dealer Tie! Game Goes To Dealer"
    message()

改成这个

if (total_hand(player) == 21) and (total_hand(dealer) == 21):         
    print "Player And Dealer Tie! Game Goes To Dealer"
    message()
elif (total_hand(player) == 21):
    print "BLACKJACK! YOU WIN!"
    message()
elif (total_hand(dealer) == 21):
    print "BLACKJACK! Sorry You Lose! Dealer Wins"                
    message()
elif (total_hand(player) > 21):
    print "BUSTED! You Lose"
    message()
elif (total_hand(dealer) > 21):
    print "Dealer Busted! You Win!"
    message()

之前,你可能无法满足所有的条件,因为最后一个条件需要的情况可能在第一个或第三个条件下就已经满足了。

撰写回答