如果,Elif,混乱

时间:2013-02-27 06:37:09

标签: python if-statement

在写一个二十一点脚本时,我遇到了一些关于如何使用'if','elif'和'else'语句的混淆。我在这里查看了关于这个主题的大部分帖子,用Google搜索,但我仍然感到困惑。 。 。我确实知道如果使用'elif'而不是重复'if'语句,当(或其中一个)'elif'语句的计算结果为True时,代码将会短路。这实际上让我更加困惑(虽然我理解使用'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 个答案:

答案 0 :(得分: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()

在您无法达到elifs语句的所有条件之前,因为满足最后一个语句所需的条件对于第一个或第三个语句都是正确的。

答案 1 :(得分:1)

您的代码的一个主要问题是您应该首先检查领带,否则您宣布玩家是赢家。

使用您的代码,无论您使用if还是elif,它实际上都没有区别。那是因为message()函数永远不会实际返回:它退出程序或递归调用main()。这不是好设计:读取代码的任何人都不会期望名为message()的函数执行其中任何一项。

我的建议是创建一个函数来检查游戏是否结束并返回描述结果的字符串。我就是这样做的;但请注意,即使在这里,您也可以使用if代替elif,因为return语句仍会退出函数。

def check_game_over(total_player, total_dealer):
    if total_dealer == 21:
        if total_player == 21:
            return "Player And Dealer Tie! Game Goes To Dealer"
        else:
            return "BLACKJACK! Sorry You Lose! Dealer Wins"              
    elif total_player == 21:
        return "BLACKJACK! YOU WIN!"
    elif total_player > 21:
        return "BUSTED! You Lose"
    elif total_dealer > 21:
        return "Dealer Busted! You Win!"
    else:
        return None

答案 2 :(得分:0)

不,有几个小的缩进错误,最后,你可以使用elif语句。这是您的代码应该是什么样的。

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()
        elif (c == "q"):
            message()
        else:
            print "Invalid Choice. . .To Quit, Press [Q]"

答案 3 :(得分:0)

在这种情况下,使用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,则可能会增加它并将其推入1&lt; = x&lt; 2范围,所以第二个子句也将被执行。为了防止这个问题,只需使用elif,保证只执行其中一个子句,第一个执行True

答案 4 :(得分:0)

如果你修改使用while内的main循环,而不是从main调用message,我建议你的程序会更短更清晰

Structured programming曾经但不再是有争议的想法,我们使用像ifelif这样的条件结构加上while之类的循环而不是其他方法来控制发生的事情下一个。您从message拨打mainos.exit的电话采用的是与结构化编程不同的策略。通过安排main重复呼叫message,您可以将自己画成一个角落。实际上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上有很多这样的说法:我知道有关结构化编程的有趣替代方案,包括递归,正确的尾调用和蹦床。对于这个特殊的问题,我建议他们不是下一步。

答案 5 :(得分:0)

一系列if/elif/elif/.../elif/else只是测试的,一个接一个地运行直到一个成功(或者直到所有这些都失败并执行else )。相比之下,if s序列只是一系列独立的测试,每个测试都在不咨询其他测试的情况下运行。

测试顺序的顺序很重要!之前的测试在之前的测试之前运行。因此,如果你这样做

def rangetest(n):
    if n >= 40:
        print "Big!"
    elif n >= 25:
        print "Medium!"
    elif n >= 10:
        print "Small!"
    else:
        print "Tiny!"

然后输入rangetest(100)将始终只打印Big!,即使其他条件都匹配。 (如果我们在此处仅使用if而不是elif,那么我们会将Big!Medium!Small!打印出来。


其他答案与您在计划中使用if/elif有关。我只想指出一件小事。

我会颠倒你的程序的逻辑。我没有让main调用函数message来调用main,而是编写一个主循环,如下所示:

def main():
    play_game()
    while 1:
        again = raw_input("Do You Want To Play Again? [Y] For Yes - Press Any Key To Quit:   ")
        if 'y' in again.lower():
            play_game()
        else:
            print "Thanks for playing!"
            return # exit main loop

然后play_game将包含游戏的主要逻辑,return代替message()。这简化了您的控制流程,因为您只需退出当前轮次(使用return),而不是通过main笨拙地“循环”message