1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        【Python】我的第一個Python游戲:石頭剪刀布

        共 19923字,需瀏覽 40分鐘

         ·

        2022-06-28 01:33

        最近有粉絲朋友跟云朵君聊到用Python做個石頭剪刀布的小游戲。我一尋思,還挺好玩。其實游戲編程是學(xué)習(xí)如何編程的一個好方法,它會使用許多我們在現(xiàn)實世界中看到的工具,還可以玩一個游戲來測試我們的編程結(jié)果!作為Python游戲編程的入門游戲:石頭剪刀布,我們今天就來一起玩一玩。

        在文中我們將一起學(xué)習(xí)如何

        • 剪刀石頭布游戲碼代碼
        • input() 接收用戶輸入
        • 使用 while 循環(huán)連續(xù)玩幾個游戲
        • Enum函數(shù)簡化代碼
        • 字典定義更復(fù)雜的規(guī)則

        什么是石頭剪刀布?

        大家以前都玩過石頭剪刀布吧。假裝你不熟悉,石頭剪刀布是一個供兩個或更多人玩的手部游戲。參與者說 "石頭、剪刀、布",然后同時將他們的手捏成石頭(拳頭)、一張布(手掌朝上)或一把剪刀(伸出兩個手指)的形狀。

        規(guī)則是直截了當(dāng)?shù)?

        • 石頭砸剪刀。
        • 包石頭。
        • 剪刀剪布。

        現(xiàn)在用了這些規(guī)則,可以開始考慮如何將它們轉(zhuǎn)化為Python代碼。

        在Python中玩單一的石頭剪刀布游戲

        使用上面的描述和規(guī)則,我們可以做一個石頭剪刀布的游戲。首先需要導(dǎo)入用來模擬計算機(jī)選擇的模塊。

        import random

        現(xiàn)在我們能夠使用隨機(jī)里面的不同工具來隨機(jī)化計算機(jī)在游戲中的行動。由于我們的用戶也需要能夠選擇行動,所以需要接受用戶的輸入。

        接收用戶輸入

        從用戶那里獲取輸入信息在Python中是非常直接的。這里的目標(biāo)是問用戶他們想選擇什么行動,然后把這個選擇分配給一個變量。

        user_action = input("輸入一個選擇(石頭、剪刀、布):")

        這將提示用戶輸入一個選擇,并將其保存在一個變量中供以后使用。用戶已經(jīng)選擇了一個行動后,輪到計算機(jī)決定做些什么。

        計算機(jī)選擇

        競爭性的石頭剪刀布游戲涉及策略

        還正有人研究并把石頭剪刀布游戲策略寫成學(xué)術(shù)論文,感興趣的小伙伴可以查看論文(傳送門:https://arxiv.org/pdf/1404.5199v1.pdf)

        研究人員將 360 名學(xué)生分成六人一組,讓他們隨機(jī)配對玩 300 輪石頭剪刀布。學(xué)生們每次贏得一輪比賽都會得到少量的錢。在他們玩游戲的過程中,研究人員觀察了玩家在輸贏時如何在三個游戲選項中輪換。

        他們發(fā)現(xiàn),“如果一名玩家在一場比賽中戰(zhàn)勝對手,她在下一場比賽中重復(fù)相同動作的概率大大高于她改變動作的概率?!?如果一名玩家輸了兩次或兩次以上,她很可能會改變她的打法,并且更有可能轉(zhuǎn)向能夠擊敗剛剛擊敗她的對手而不是她的對手剛剛擊敗她的動作。例如,如果小紅對小明的石頭玩剪刀輸了,小紅最有可能改用紙,這會打敗小明的石頭。根據(jù)研究,這是一個合理的策略,因為小明很可能會繼續(xù)玩已經(jīng)獲勝的動作。作者將此稱為“贏-留,輸-轉(zhuǎn)變”策略

        因此,這是在剪刀石頭布上獲勝的最佳方法:如果你輸?shù)袅说谝惠啠袚Q到擊敗對手剛剛玩過的動作。如果你贏了,不要繼續(xù)玩同樣的動作,而是換成能打敗你剛剛玩的動作的動作。換句話說,玩你失敗的對手剛剛玩的動作。也就是說:你用石頭贏了一輪別人的剪刀,他們即將改用布,此時你應(yīng)該改用剪刀。

        根據(jù)上述的游戲策略,試圖開發(fā)一個模型,應(yīng)該需要花費(fèi)不少的時間。為了簡便,我們讓計算機(jī)選擇一個隨機(jī)的行動來節(jié)省一些時間。隨機(jī)選擇就是讓計算機(jī)選擇一個偽隨機(jī)值。

        可以使用 random.choice() 來讓計算機(jī)在這些動作中隨機(jī)選擇。

        possible_actions = ["石頭""剪刀""布"]
        computer_action = random.choice(possible_actions)

        這允許從列表中選擇一個隨機(jī)元素。我們也可以打印出用戶和計算機(jī)的選擇。

        print(f"\n你選擇了 {user_action}
               計算機(jī)選擇了 {computer_action}.\n"
        )

        打印輸出用戶和計算機(jī)的操作對用戶來說是有幫助的,而且還可以幫助我們在以后的調(diào)試中,以防結(jié)果不大對勁。

        判斷輸贏

        現(xiàn)在,兩個玩家都做出了選擇,我們只需要使用if ... elif ... else 代碼塊方法來決定誰輸誰贏,接下來比較玩家的選擇并決定贏家。

        if user_action == computer_action:
            print(f"兩個玩家都選擇了 {user_action}. 這是一個平局!")
        elif user_action == "石頭":
            if computer_action == "剪刀":
                print("石頭砸碎剪刀!你贏了!")
            else:
                print("布包住石頭!你輸了。")
        elif user_action == "布":
            if computer_action == "石頭":
                print("布包住石頭!你贏了!")
            else:
                print("剪刀剪碎布!你輸了。")
        elif user_action == "剪刀":
            if computer_action == "布":
                print("剪刀剪碎布!你贏了!")
            else:
                print("石頭砸碎剪刀!你輸了。")

        通過先比較平局條件,我們擺脫了相當(dāng)多的情況。否則我們就需要檢查 user_action 的每一個可能的動作,并與 computer_action 的每一個可能的動作進(jìn)行比較。通過先檢查平局條件,我們能夠知道計算機(jī)選擇了什么,只需對 computer_action 進(jìn)行兩次條件檢查。

        所以完整代碼現(xiàn)在應(yīng)該是這樣的:

        上下滑動查看更多源碼

        import random

        user_action = input("輸入一個選擇(石頭、剪刀、布):")
        possible_actions = ["石頭""剪刀""布"]
        computer_action = random.choice(possible_actions)
        print(f"\n你選擇了 {user_action}, 計算機(jī)選擇了 {computer_action}.\n")

        if user_action == computer_action:
            print(f"兩個玩家都選擇了 {user_action}. 這是一個平局!")
        elif user_action == "石頭":
            if computer_action == "剪刀":
                print("石頭砸碎剪刀!你贏了!")
            else:
                print("布包住石頭!你輸了。")
        elif user_action == "布":
            if computer_action == "石頭":
                print("布包住石頭!你贏了!")
            else:
                print("剪刀剪碎布!你輸了。")
        elif user_action == "剪刀":
            if computer_action == "布":
                print("剪刀剪碎布!你贏了!")
            else:
                print("石頭砸碎剪刀!你輸了。")

        現(xiàn)在我們已經(jīng)寫好了代碼,可以接受用戶的輸入,并為計算機(jī)選擇一個隨機(jī)動作,最后決定勝負(fù)!這個初級代碼只能讓我們和電腦玩一局。

        連續(xù)打幾場比賽

        雖然單一的剪刀石頭布游戲比較有趣,但如果我們能連續(xù)玩幾場,不是更好嗎?此時我們想到 循環(huán) 是創(chuàng)建重復(fù)性事件的一個好方法。我們可以用一個 while循環(huán) 來無限期地玩這個游戲。

        import random
        while True:
            # 包住上完整代碼
            play_again = input("Play again? (y/n): ")
            if play_again.lower() != "y":
                break

        注意我們補(bǔ)充的代碼,檢查用戶是否想再玩一次,如果他們不想玩就中斷,這一點很重要。如果沒有這個檢查,用戶就會被迫玩下去,直到他們用Ctrl+C或其他的方法強(qiáng)制終止程序。

        對再次播放的檢查是對字符串 "y" 的檢查。但是,像這樣檢查特定的東西可能會使用戶更難停止游戲。如果用戶輸入 "yes""no" 怎么辦?字符串比較往往很棘手,因為我們永遠(yuǎn)不知道用戶可能輸入什么。他們可能會做所有的小寫字母,所有的大寫字母,甚至是輸入中文。

        下面是幾個不同的字符串比較的結(jié)果。

        >>> play_again = "yes"
        >>> play_again == "n"
        False
        >>> play_again != "y"
        True

        其實這不是我們想要的。如果用戶輸入 "yes",期望再次游戲,卻被踢出游戲,他們可能不會太高興。

        enum.IntEnum描述動作

        我們在之前的示意代碼中,定義的是中文字符串,但實際使用python開發(fā)時,代碼里一般不使用中文(除了注釋),因此了解這一節(jié)還是很有必要的。

        所以我們將把石頭剪刀布翻譯成:"rock", "scissors", "paper"。

        字符串比較可能導(dǎo)致像我們上面看到的問題,所以需要盡可能避免。然而,我們的程序要求的第一件事就是讓用戶輸入一個字符串!如果用戶錯誤地輸入了 "Rock "或 "rOck "怎么辦?如果用戶錯誤地輸入 "Rock "或 "rOck "怎么辦?大寫字母很重要,所以它們不會相等。

        >>> print("rock" == "Rock")
        False

        由于大寫字母很重要,所以 "r""R" 并不相等。一個可能的解決方案是用數(shù)字代替。給每個動作分配一個數(shù)字可以為我們省去一些麻煩。

        ROCK_ACTION = 0
        SCISSORS_ACTION = 1
        PAPER_ACTION = 2

        我們通過分配的數(shù)字來引用不同的行動,整數(shù)不存在與字符串一樣的比較問題,所以這是可行的?,F(xiàn)在讓用戶輸入一個數(shù)字,并直接與這些值進(jìn)行比較。

        user_input = input("輸入您的選擇 (石頭[0], 剪刀[1], 布[2]): ")
        user_action = int(user_input)
        if user_action == ROCK_ACTION:
            # 處理 ROCK_ACTION

        因為input()返回一個字符串,需要用int() 把返回值轉(zhuǎn)換成一個整數(shù)。然后可以將輸入值與上面的每個動作進(jìn)行比較。雖然這樣做效果很好,但它可能依賴于對變量的正確命名。其實有一個更好的方法是使用**enum.IntEnum**來自定義動作類。

        我們使用 enum.IntEnum創(chuàng)建屬性并給它們分配類似于上面所示的值,將動作歸入它們自己的命名空間,使代碼更有表現(xiàn)力。

        from enum import IntEnum
        class Action(IntEnum):
            Rock = 0
            Scissors = 1
            Paper = 2

        這創(chuàng)建了一個自定義Action,可以用它來引用我們支持的不同類型的Action。它的工作原理是將其中的每個屬性分配給我們指定的值。

        兩個動作的比較是直截了當(dāng)?shù)?,現(xiàn)在它們有一個有用的類名與之相關(guān)。

        >>> Action.Rock == Action.Rock
        True

        因為成員的值是相同的,所以比較的結(jié)果是相等的。類的名稱也使我們想比較兩個動作的意思更加明顯。

        注意:要了解更多關(guān)于enum的信息,請查看官方文檔[1]

        我們甚至可以從一個 int 創(chuàng)建一個 Action。

        >>> Action.Rock == Action(0)
        True
        >>> Action(0)
        <Action.Rock: 0>

        Action 查看傳入的值并返回適當(dāng)?shù)?Action。因此現(xiàn)在可以把用戶的輸入作為一個int,并從中創(chuàng)建一個Action,媽媽再也不用擔(dān)心拼寫問題了!

        程序流程(圖)

        雖然剪刀石頭布看起來并不復(fù)雜,但仔細(xì)考慮玩剪刀石頭布的步驟是很重要的,這樣才能確保我們的程序涵蓋所有可能的情況。對于任何項目,即使是小項目,我們有必要創(chuàng)建一個所需行為的流程圖并圍繞它實現(xiàn)代碼。我們可以用一個列表來達(dá)到類似的效果,但它更難捕捉到諸如循環(huán)和條件等相關(guān)邏輯。

        流程圖不需要過于復(fù)雜,甚至不需要使用真正的代碼。只要提前描述所需的行為,就可以幫助我們在問題發(fā)生之前解決問題

        這里有一個流程圖,描述了一個單一的剪刀石頭布游戲。

        每個玩家選擇一個行動,然后確定一個贏家。這個流程圖對于我們所編碼的單個游戲來說是準(zhǔn)確的,但對于現(xiàn)實生活中的游戲來說卻不一定準(zhǔn)確。在現(xiàn)實生活中,玩家會同時選擇他們的行動,而不是像流程圖中建議的那樣一次一個。

        然而,在編碼版本中,這一點是可行的,因為玩家的選擇對電腦是隱藏的,而電腦的選擇對玩家也是隱藏的。兩個玩家可以在不同的時間做出選擇而不影響游戲的公平性。

        流程圖可以幫助我們在早期發(fā)現(xiàn)可能的錯誤,也可以讓我們看到是否要增加更多的功能。例如這個流程圖,描述了如何重復(fù)玩游戲,直到用戶決定停止。

        如果不寫代碼,我們可以看到第一個流程圖沒有辦法重復(fù)玩。我們可以使用這種繪制流程圖的方法在編程前解決類似的問題,這有助于我們碼出更整潔、更易于管理的代碼!

        拆分代碼并封裝函數(shù)

        現(xiàn)在我已經(jīng)用流程圖概述了程序的流程,我們可以試著組織我們的代碼,使它更接近于所確定的步驟。一個方法是為流程圖中的每個步驟創(chuàng)建一個函數(shù)。 其實函數(shù)是一種很好的方法,可以將大塊的代碼拆分成更小的、更容易管理的部分。

        我們不一定需要為條件檢查的再次播放創(chuàng)建一個函數(shù),但如果我們愿意,我們可以。如果我們還沒有,我們可以從導(dǎo)入隨機(jī)開始,并定義我們的Action類。

        import random
        from enum import IntEnum

        class Action(IntEnum):
            Rock = 0
            Scissors = 1
            Paper = 2

        接下來定義 get_user_selection() 的代碼,它不接受任何參數(shù)并返回一個 Action。

        def get_user_selection():
            user_input = input("輸入您的選擇 (石頭[0], 剪刀[1], 布[2]):")
            selection = int(user_input)
            action = Action(selection)
            return action

        注意這里是如何將用戶的輸入作為一個 int,然后得到一個 Action。不過,給用戶的那條長信息有點麻煩。如果我們想增加更多的動作,就不得不在提示中添加更多的文字。

        我們可以使用一個列表推導(dǎo)式來生成一部分輸入。

        def get_user_selection():
            choices = [f"{action.name}[{action.value}]" for action in Action]
            choices_str = ", ".join(choices)
            selection = int(input(f"輸出您的選擇 ({choices_str}): "))
            action = Action(selection)
            return action

        現(xiàn)在不再需要擔(dān)心將來添加或刪除動作的問題了!接下來測試一下,我們可以看到代碼是如何提示用戶并返回一個與用戶輸入值相關(guān)的動作。

        >>> get_user_selection()
        輸入您的選擇 (石頭[0], 剪刀[1], 布[2]): 0
        <Action.Rock: 0>

        現(xiàn)在我們需要一個函數(shù)來獲取計算機(jī)的動作。和 get_user_selection() 一樣,這個函數(shù)應(yīng)該不需要參數(shù),并返回一個 Action。因為 Action 的值范圍是0到2,所以使用 random.randint() 幫助我們在這個范圍內(nèi)生成一個隨機(jī)數(shù)。

        random.randint() 返回一個在指定的最小值和最大值(包括)之間的隨機(jī)值。可以使用 len() 來幫助計算代碼中的上限應(yīng)該是多少。

        def get_computer_selection():
            selection = random.randint(0, len(Action) - 1)
            action = Action(selection)
            return action

        因為 Action 的值從0開始計算,而len()從1開始計算,所以需要額外做個 len(Action)-1

        測試該函數(shù),它簡單地返回與隨機(jī)數(shù)相關(guān)的動作。

        >>> get_computer_selection()
        <Action.Scissors: 2>

        看起來還不錯!接下來,需要一個函數(shù)來決定輸贏,這個函數(shù)將接受兩個參數(shù),用戶的行動和計算機(jī)的行動。它只需要將結(jié)果顯示在控制臺上,而不需要返回任何東西。

        def determine_winner(user_action, computer_action):
          if user_action == computer_action:
                print(f"兩個玩家都選擇了 {user_action.name}. 這是一個平局!")
            elif user_action == Action.Rock:
                if computer_action == Action.Scissors:
                    print("石頭砸碎剪刀!你贏了!")
                else:
                    print("布包住石頭!你輸了。")
            elif user_action == Action.Paper:
                if computer_action == Action.Rock:
                    print("布包住石頭!你贏了!")
                else:
                    print("剪刀剪碎布!你輸了。")
            elif user_action == Action.Scissors:
                if computer_action == Action.Paper:
                    print("剪刀剪碎布!你贏了!")
                else:
                    print("石頭砸碎剪刀!你輸了。")

        這里決定勝負(fù)的寫法與剛開始的代碼非常相似。而現(xiàn)在可以直接比較行動類型,而不必?fù)?dān)心那些討厭的字符串!

        我們甚至可以通過向 determinal_winner() 傳遞不同的參數(shù)來測試函數(shù),看看會打印出什么。

        >>> determine_winner(Action.Rock, Action.Scissors)
        石頭砸碎剪刀!你贏了!

        既然我們要從一個數(shù)字創(chuàng)建一個動作,如果用戶想用數(shù)字3創(chuàng)建一個動作,會發(fā)生什么?(我們定義的最大數(shù)字是2)。

        >>> Action(3)
        ValueError: 3 is not a valid Action

        報錯了!這并不是我們希望發(fā)生這種情況。接下來可以在流程圖上添加一些邏輯,來補(bǔ)充這個 bug,以確保用戶始終輸入一個有效的選擇。

        在用戶做出選擇后立即加入檢查是有意義的。

        如果用戶輸入了一個無效的值,那么我們就重復(fù)這個步驟來獲得用戶的選擇。對用戶選擇的唯一真正要求是它在【0, 1, 2】之間的一個數(shù)。如果用戶的輸入超出了這個范圍,那么就會產(chǎn)生一個ValueError異常。我們可以處理這個異常,從而不會向用戶顯示默認(rèn)的錯誤信息。

        現(xiàn)在我們已經(jīng)定義了一些反映流程圖中的步驟的函數(shù),我們的游戲邏輯就更有條理和緊湊了。這就是我們的while循環(huán)現(xiàn)在需要包含的所有內(nèi)容。

        while True:
            try:
                user_action = get_user_selection()
            except ValueError as e:
                range_str = f"[0, {len(Action) - 1}]"
                print(f"Invalid selection. Enter a value in range {range_str}")
                continue

            computer_action = get_computer_selection()
            determine_winner(user_action, computer_action)

            play_again = input("Play again? (y/n): ")
            if play_again.lower() != "y":
                break

        這看起來是不是干凈多了?注意,如果用戶未能選擇一個有效的范圍,那么我們就使用continue而不是break。這使得代碼繼續(xù)到循環(huán)的下一個迭代,而不是跳出該循環(huán)。

        Rock Paper Scissors … Lizard Spock

        如果我們看過《生活大爆炸》,那么我們可能對石頭剪子布蜥蜴斯波克很熟悉。如果沒有,那么這里有一張圖,描述了這個游戲和決定勝負(fù)的規(guī)則。

        我們可以使用我們在上面學(xué)到的同樣的工具來實現(xiàn)這個游戲。例如,我們可以在Action中加入LizardSpock的值。然后我們只需要修改 get_user_selection()get_computer_selection(),以納入這些選項。然而,更新determinal_winner()。

        與其在我們的代碼中加入大量的if ... elif ... else語句,我們可以使用字典來幫助顯示動作之間的關(guān)系。字典是顯示 鍵值關(guān)系 的一個好方法。在這種情況下, 可以是一個動作,如剪刀,而 可以是一個它所擊敗的動作的列表。

        那么,對于只有三個選項的 determinal_winner() 來說,這將是什么樣子呢?好吧,每個 Action 只能打敗一個其他的 Action,所以列表中只包含一個項目。下面是我們的代碼之前的樣子。

        def determine_winner(user_action, computer_action):
            if user_action == computer_action:
                print(f"Both players selected {user_action.name}. It's a tie!")
            elif user_action == Action.Rock:
                if computer_action == Action.Scissors:
                    print("Rock smashes scissors! You win!")
                else:
                    print("Paper covers rock! You lose.")
            elif user_action == Action.Paper:
                if computer_action == Action.Rock:
                    print("Paper covers rock! You win!")
                else:
                    print("Scissors cuts cpaper! You lose.")
            elif user_action == Action.Scissors:
                if computer_action == Action.Paper:
                    print("Scissors cuts cpaper! You win!")
                else:
                    print("Rock smashes scissors! You lose.")

        現(xiàn)在,我們可以有一個描述勝利條件的字典,而不是與每個行動相比較。

        def determine_winner(user_action, computer_action):
            victories = {
                Action.Rock: [Action.Scissors],  # Rock beats scissors
                Action.Paper: [Action.Rock],  # Paper beats rock
                Action.Scissors: [Action.Paper]  # Scissors beats cpaper
            }

            defeats = victories[user_action]
            if user_action == computer_action:
                print(f"Both players selected {user_action.name}. It's a tie!")
            elif computer_action in defeats:
                print(f"{user_action.name} beats {computer_action.name}! You win!")
            else:
                print(f"{computer_action.name} beats {user_action.name}! You lose.")

        我們還是和以前一樣,先檢查平局條件。但我們不是比較每一個 Action,而是比較用戶輸入的 Action 與電腦輸入的 Action。由于鍵值對是一個列表,我們可以使用成員運(yùn)算符 in 來檢查一個元素是否在其中。

        由于我們不再使用冗長的if ... elif ... else語句,為這些新的動作添加檢查是相對容易的。我們可以先把LizardSpock加入到Action中。

        class Action(IntEnum):
            Rock = 0
            Scissors = 1
            Paper = 2
            Lizard = 3
            Spock = 4

        接下來,從圖中添加所有的勝利關(guān)系。

        victories = {
            Action.Scissors: [Action.Lizard, Action.Paper],
            Action.Paper: [Action.Spock, Action.Rock],
            Action.Rock: [Action.Lizard, Action.Scissors],
            Action.Lizard: [Action.Spock, Action.Paper],
            Action.Spock: [Action.Scissors, Action.Rock]
        }

        注意,現(xiàn)在每個 Action 都有一個包含可以擊敗的兩個元素的列表。而在基本的 "剪刀石頭布 " 實現(xiàn)中,只有一個元素。

        我們寫了 get_user_selection() 來適應(yīng)新的動作,所以不需要改變該代碼的任何內(nèi)容。get_computer_selection() 的情況也是如此。由于 Action 的長度發(fā)生了變化,隨機(jī)數(shù)的范圍也將發(fā)生變化。

        看看現(xiàn)在的代碼有多簡潔,有多容易維護(hù)管理!完整程序的完整代碼:

        上下滑動查看更多源碼

        import random
        from enum import IntEnum

        class Action(IntEnum):
            Rock = 0
            Paper = 1
            Scissors = 2
            Lizard = 3
            Spock = 4

        victories = {
            Action.Scissors: [Action.Lizard, Action.Paper],
            Action.Paper: [Action.Spock, Action.Rock],
            Action.Rock: [Action.Lizard, Action.Scissors],
            Action.Lizard: [Action.Spock, Action.Paper],
            Action.Spock: [Action.Scissors, Action.Rock]
        }

        def get_user_selection():
            choices = [f"{action.name}[{action.value}]" for action in Action]
            choices_str = ", ".join(choices)
            selection = int(input(f"Enter a choice ({choices_str}): "))
            action = Action(selection)
            return action

        def get_computer_selection():
            selection = random.randint(0, len(Action) - 1)
            action = Action(selection)
            return action

        def determine_winner(user_action, computer_action):
            defeats = victories[user_action]
            if user_action == computer_action:
                print(f"Both players selected {user_action.name}. It's a tie!")
            elif computer_action in defeats:
                print(f"{user_action.name} beats {computer_action.name}! You win!")
            else:
                print(f"{computer_action.name} beats {user_action.name}! You lose.")

        while True:
            try:
                user_action = get_user_selection()
            except ValueError as e:
                range_str = f"[0, {len(Action) - 1}]"
                print(f"Invalid selection. Enter a value in range {range_str}")
                continue

            computer_action = get_computer_selection()
            determine_winner(user_action, computer_action)

            play_again = input("Play again? (y/n): ")
            if play_again.lower() != "y":
                break

        到這里我們已經(jīng)用Python代碼實現(xiàn)了rock paper scissors lizard Spock 。接下來你就可以仔細(xì)檢查一下,確保我們沒有遺漏任何東西,然后進(jìn)行一次游戲。

        總結(jié)

        看到這里,必須點個贊,因為我們剛剛完成了第一個Python游戲?,F(xiàn)在,我們知道了如何從頭開始創(chuàng)建剪刀石頭布游戲,而且我可以以最小的代價擴(kuò)展游戲中可能的行動數(shù)量。

        參考資料

        [1]

        官方文檔: https://docs.python.org/3/library/enum.html


        往期精彩回顧




        瀏覽 67
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            一级a一级a爰片免费免会员四虎 | 性欧美大战久久久久久久83 | 又粗又硬又爽又爱成人的视频 | 天堂AV导航 | 国模乳神张雪馨大尺度视频在线 | 一级黄色免费大片 | 色一级老女人大毛片 | 久久久久无码精品国产H动漫猫咪 | 爱情岛成人论坛 | 国产偷 久久一级精品A网站 |