-2

While writing a Blackjack script, I've come across some confusion on how I should use 'if', 'elif', and 'else' statements. I looked at most of the posts on the subject here, googled it, but am still confused. . .I did learn that if 'elif' is used instead of repeating 'if' statements, the code will short circuit when the (or one of the) 'elif' statements evaluates to True. This has actually confused me more (although I understand the concept of what happens when using 'elif' and shortcircuiting). The first 5 'if' statement illustrates this. Had I used 'elif' instead of 'if', the code may never reach the last condition if both player and dealer hit 21. . .After this though, it seems I could have used 'elif' statements or just leave it the way it is. . .So, my question is, did I use them correctly in the rest of main()? If not, how would you do it? Thank you very much.

# 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()
4

6 回答 6

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 达到语句的所有条件之前,因为满足最后一条语句所需的条件对于第一条或第三条语句都是正确的。

于 2013-02-27T06:55:47.943 回答
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
于 2013-02-27T06:42:58.837 回答
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小于一,它也将小于二。有时可以通过正确检查来避免这种情况,如下所示:

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

但是,如果 do_something() 也修改了 x,它可能会增加它并将其推送到 1 <= x < 2 范围内,因此第二个子句也将被执行。为了防止该问题,只需使用elif, that one 保证仅执行其中一个子句,即第一个计算结果为 的子句True

于 2013-02-27T06:44:53.307 回答
1

如果您修改为在 of 中使用while循环main,而不是调用mainfrom message,我建议您的程序最终会更短更清晰。

结构化编程是曾经但不再有争议的想法,我们使用条件构造(如if和加elif循环while),而不是其他控制接下来发生的方法。或者,您的呼叫来自message于,main并且os.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 上有很多:我知道结构化编程的有趣替代方案,包括递归、适当的尾调用和蹦床。对于这个特定的问题,我建议它们不是下一步。 )

于 2013-02-27T06:45:58.707 回答
1

一个序列if/elif/elif/.../elif/else只是一个测试,一个接一个地运行,直到一个成功(或者直到它们都失败并被else执行)。相反,ifs 序列只是一系列独立测试,每个测试都在不咨询其他测试的情况下运行。

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

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

然后放入rangetest(100)将始终 print only Big!,即使其余条件都匹配。(如果我们只if在这里使用而不是elif,那么我们会得到Big!Medium!并且Small!全部打印出来)。


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

我会颠倒你程序的逻辑。我不会调用一个依次调用main的函数,而是编写一个如下所示的主循环messagemain

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.

于 2013-02-27T07:14:43.273 回答
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]"
于 2013-02-27T06:41:01.977 回答