<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          第四章5:創(chuàng)建猜單詞游戲(Hangman)

          共 8784字,需瀏覽 18分鐘

           ·

          2021-03-08 22:26

          星期五:創(chuàng)建猜單詞游戲(Hangman)

          隨著前幾周的學(xué)習(xí),我們會發(fā)現(xiàn)這些項(xiàng)目代碼通常會變的越來越長。今天,我們將利用過去四個(gè)天學(xué)到的所有概念來構(gòu)建Hangman游戲。正如往常一樣,隨著項(xiàng)目代碼寫入,我們將引入新的概念。今天,我們的目標(biāo)是創(chuàng)建功能齊全的Hangman游戲,在這個(gè)游戲里,我們可以猜詞,減少生命值,并最后贏或輸?shù)粲螒?。在這個(gè)游戲中,我們不會創(chuàng)建圖象。在我們共同完成項(xiàng)目后,你可以根據(jù)自己的需求隨意添加圖形。

          為了完成本課程,讓我們繼續(xù)從上一個(gè)筆記本文件“ Week_04”開始,并在下面添加一個(gè)標(biāo)記為“星期五項(xiàng)目:創(chuàng)建猜單詞游戲(Hangman)”的Markdown模塊。

          最終設(shè)計(jì)

          與往常一樣,我們希望在開始編碼之前先對最終設(shè)計(jì)進(jìn)行規(guī)劃布局。與上周不同的是,本周將不會基于圖形,因此我們將重點(diǎn)介紹運(yùn)行程序所需的邏輯和必要步驟。對我們來說幸運(yùn)的是,邏輯本質(zhì)上是玩游戲所需的步驟:

          1.選擇一個(gè)要玩的單詞。

          2.要求玩家輸入。

          3.檢查是否猜對。

              a.如果猜對,請?jiān)谶m當(dāng)?shù)奈恢蔑@示字母。

              b.如果猜錯(cuò),喪失一條命。

          4.繼續(xù)執(zhí)行步驟2和3,直到發(fā)生以下情況之一:

              a.玩家猜詞正確。

              b.玩家喪失全部生命。

          這是主要的游戲玩法。在實(shí)際運(yùn)行游戲之前,我們還需要執(zhí)行其他幾個(gè)步驟,如聲明游戲變量;但是,在我們開始編碼之前需要布置游戲所需要的主要功能。知道這種結(jié)構(gòu)將使我們能夠條理清晰的創(chuàng)建程序。

          以前的線符號介紹

          正如我們在第一周添加線號一樣,我們也將介紹這個(gè)項(xiàng)目以及所有其他項(xiàng)目的線符號概念。由于需要編輯以前編寫的行,甚至需要在項(xiàng)目的中間添加代碼,我們這里將介紹線符號的概念。這些符號將通過三個(gè)空方塊來顯示,代表先前編寫的代碼。你可以在下面的例子中看到:

          1|if num > 1: ???
          3|    # 新代碼將寫在這里
          5|    print(???

          當(dāng)我們在先前編寫的代碼之間添加行時(shí),我將使用這三個(gè)正方形來表示哪一行應(yīng)在我們正在編寫的代碼之上和之下。這也意味著你應(yīng)該保持不變。當(dāng)我們需要覆蓋上一行時(shí),書中會明確的進(jìn)行說明。當(dāng)你看到這三個(gè)正方形時(shí),請務(wù)必要注意每行代碼的行號,因?yàn)檫@將幫助你了解是否錯(cuò)過了相關(guān)代碼行。


          注意:單擊單元格的側(cè)面后,按“ L”打開線。


          導(dǎo)入庫

          我們將在一個(gè)單元中編寫該程序,該程序代碼大約有50行。第一步是導(dǎo)入一些我們需要用到的庫:

          1# 導(dǎo)入庫
          2from random import choice
          3from IPython.display import clear_output

          代碼塊第二行將從random庫中導(dǎo)入一個(gè)名為“ choice”的函數(shù),該函數(shù)將從列表中隨機(jī)選擇一個(gè)元素。我們將使用這個(gè)函數(shù)來隨機(jī)選擇單詞。代碼塊第三行是導(dǎo)入Jupyter Notebook專用功能,目的是清除輸出。我們在使用循環(huán)時(shí),如果不清除輸出,則循環(huán)將不斷的相互疊加輸出。

          聲明游戲變量

          接下來,我們要了解運(yùn)行游戲所需的變量并聲明它們。如果你考慮“ Hangman”游戲以及我們需要跟蹤的內(nèi)容,則需要跟蹤玩家的生命,他們嘗試猜測的單詞,可供選擇的單詞列表以及游戲是否結(jié)束:

          5# 聲明游戲變量
          6| words = [ "tree""basket""chair""paper""python" ]
          7| word = choice(words) # 從單詞列表中隨機(jī)選擇一個(gè)單詞
          8| guessed, lives, game_over = [ ], 7False # 多個(gè)變量分配元素

          代碼塊第七行聲明了一個(gè)名為word的變量,它將從單詞列表中隨機(jī)選擇一個(gè)。代碼塊 第八行一起聲明了三個(gè)變量。gussed變量將被賦予一個(gè)空列表的值,lives變量將被分配元素7,game_over變量將被聲明為布爾值False。


          注意:在編寫代碼時(shí),請隨時(shí)用打印語句來檢查每個(gè)變量的值。這有助于了解我們的聲明是否為我們所需要的。


          生成隱藏字

          在游戲過程中,我們希望玩家能夠看到所猜單詞包含多少個(gè)字母。為此,我們可以創(chuàng)建一個(gè)字符串列表,其中每個(gè)字符串都是一個(gè)下劃線。列表中的元素?cái)?shù)量將設(shè)置為所選單詞的相同長度:

          10# 創(chuàng)建一個(gè)與單詞長度相同的且包含下劃線的列表
          11| guesses = [ "_ " ]  * len(word)

          在第11行上,我們聲明了一個(gè)名為guesses的變量,該變量設(shè)置為包括下劃線的列表。通過將列表乘以單詞的長度,可以將列表內(nèi)的元素復(fù)制,得到與單詞長度一致的列表。

          創(chuàng)建游戲循環(huán)

          無論程序的大小,每個(gè)游戲都有一個(gè)主循環(huán)。我們的主循環(huán)將執(zhí)行我們在“最終設(shè)計(jì)”部分中定義的邏輯。讓我們采取一些小步驟,而非一次寫完全部代碼。第一步是可以接受玩家輸入并停止游戲:

          13# 創(chuàng)建游戲主循環(huán)
          14while not game_over:
          15|  ans = input("Type quit or guess a letter: ").lower( )
          17|  if ans == "quit":
          18|   print("Thanks for playing.")
          19|   game_over = True

          繼續(xù)并運(yùn)行這一代碼塊。如果鍵入“ quit”,game_over變?yōu)門rue(僅當(dāng)我們輸入“ quit”時(shí)才會發(fā)生),則程序停止循環(huán)。


          注意:在繼續(xù)操作之前,請始終確保代碼塊運(yùn)行完畢。


          輸出游戲信息

          接下來,我們開始向玩家輸出相關(guān)游戲信息。讓我們以一種特定格式的語句輸出他們的生命值和試圖猜測的單詞:

          14while not game_over: ???
          15# 輸出游戲信息
          16|  hidden_word = "".join(guesses)
          17|  print( "Word to guess: {}".format(hidden_word) )
          18|  print( "Lives: {}".format(lives) )
          20|  ans = input( ???

          繼續(xù)并運(yùn)行這一代碼塊。根據(jù)所選擇的單詞,你將獲得不同的輸出。如果選擇的單詞是四個(gè)字母,我們將得到“猜單詞:_ _ _ _”和“生命值:7”的輸出。格式化字符不是什么新鮮事物,但是對于第16行的代碼你是否知道是用來實(shí)現(xiàn)什么功能的嗎?我們之所以能夠在第17行中輸出帶下劃線的字符串,正是因?yàn)槭褂昧薺oin方法。它作用是將我們希望猜測的列表中的所有項(xiàng)目以特定字符連接在一起。例如:

          chars = ['h''e''l''l''o']
          print('-'.join(chars))

          運(yùn)行這一代碼,結(jié)果將輸出“ h-e-l-l-o”。這是一種將列表顯示為字符串的簡單方法。

          檢查猜測結(jié)果

          接下來,所要實(shí)現(xiàn)的功能是檢查并查看玩家的輸入是否正確。我們暫時(shí)不會更改任何字母,因?yàn)槲覀兪紫纫_保我們可以識別正確的猜測,并輸出他們正確猜出的字母或猜錯(cuò)將減少一個(gè)生命值:

          24|    game_over = True ???
          25|   elif ans in word: # 檢查字母是否在單詞中
          26|    print("You guessed correctly!")
          27|   else# 否則,減少一個(gè)生命值
          28|    lives -= 1  # 等價(jià)于 lives = lives - 1
          29|    print("Incorrect, you lost a life.")

          繼續(xù)并運(yùn)行這一代碼塊。如果你繼續(xù)猜錯(cuò),就會發(fā)現(xiàn)生命將降至零。在測試中,一定要輸入所猜單詞的正確字母和不正確字母,以便全面測試程序是否可行。

          清空輸出

          現(xiàn)在,我們對程序進(jìn)行了進(jìn)一步的學(xué)習(xí),可以看到程序循環(huán)不斷的在之前輸出的信息下方輸出信息。讓我們開始清除輸出:

          20|  ans = input( ???
          22|  clear_output( ) # 清除之前輸出的全部信息
          24|  if ans == 'quit': ???

          繼續(xù)并運(yùn)行這一代碼塊。你將注意到之前的信息無論有多少都會被清除。這也是Jupyter Notebook的特殊功能。

          創(chuàng)建生命值降低條件

          下面的操作邏輯將是創(chuàng)建一種減少生命值的方法,以便于玩家的生命值降低到零:

          31|   print('Incorrect, ???
          33|  if lives <= 0:
          34|   print("You lost all your lives, you lost!")
          35|   game_over = True

          繼續(xù)并運(yùn)行這一代碼塊。現(xiàn)在如果玩家失去了全部生命值,游戲?qū)V惯\(yùn)行并告訴玩家生命值已全部丟失,玩家已出局。記住,只有當(dāng)變量game_over為True時(shí),循環(huán)才會停止運(yùn)行。這也意味著我們曾經(jīng)設(shè)置的五次生命值已經(jīng)變?yōu)榱肆恪?/p>

          處理正確猜詞

          現(xiàn)在我們已經(jīng)能夠處理猜錯(cuò)的情況了,接下來我們還要有能力處理猜詞正確的情況。為了理解如何更改字母的顯示,我們首先需要記住輸出的結(jié)果是什么。我們的guesses列表將會變?yōu)橐粋€(gè)字符串并進(jìn)行輸出。這就意味著當(dāng)玩家猜詞正確,我們將改變在他們一貫位置上guesses列表中的元素。列表與我們代碼塊開始選擇的單詞的長度相同,所以每一個(gè)下標(biāo)都代表了一個(gè)字母的位置。如以單詞“sport”為例,第一個(gè)下標(biāo)在“_____ _ _ _ _”將代表“s _ _ _”。我們僅僅需要包含被猜測的字母列表中使用正確的下標(biāo)。要實(shí)現(xiàn)這一功能,我們可以通過一個(gè)for循環(huán)和追蹤索引做到這一點(diǎn):

          28|   print('You guessed correctly!') ???
          30|   # 創(chuàng)建循環(huán)以將下劃線更改為正確的字母
          31|   for i in range(len(word)):
          32|    if word[i] == ans[i]: # 比較索引的值
          33|     guesses[i] = ans[i]
          34|  else: ???

          繼續(xù)并運(yùn)行這一代碼塊?,F(xiàn)在,當(dāng)猜測正確的字母時(shí),它將輸出更改。for循環(huán)正在循環(huán)到單詞的長度,并且我們使用變量“ i”來進(jìn)行跟蹤索引。然后,我們檢查每個(gè)字符是否等于猜出的字母。如果是,則將項(xiàng)目從下劃線更改為該索引下的字母。為更清楚的理解,請查看表4-5中有關(guān)該過程的示例。讓我們在單詞中使用“ pop”,在“ p”中使用為猜測。

          表4-5跟蹤索引上的值來檢查是否猜對

          ans值 i值 列表中第i個(gè)索引的值 條件值 改變后猜測的值
          ‘p’ 0 ‘p’ True [‘p’, ‘_’, ‘-’]
          ‘p’ 1 ‘o’ False [‘p’, ‘_’,  ‘-’]
          ‘p’ 2 ‘p’ True [‘p’, ‘_’, ‘p’]

          創(chuàng)建一個(gè)取勝條件

          完成該項(xiàng)目的最后步驟中的一個(gè)條件就是建立獲勝條件。為了獲勝,玩家需要猜測所選隨機(jī)詞中的所有字母。我們已經(jīng)跟蹤他們正確猜出的單詞,所以我們只需要檢查一下這些隨機(jī)詞:

          40|   game_over = True ???
          41|  elif word == "".join(guesses):
          42|   print("Congratulations, you guessed it correctly!")
          43|   game_over = True

          繼續(xù)并運(yùn)行這一代碼塊?,F(xiàn)在,如果玩家猜對了所有字母,便可以取得獲勝。我們使用與之前相同的join方法,將列表轉(zhuǎn)換為字符串,因此,如果列表中仍有下劃線,則連接的字符串將不等于隨機(jī)詞。然后,我們打印出一個(gè)祝賀語句,并將我們的game_over變量更改為True來結(jié)束循環(huán)。

          輸出猜測的字母

          盡管我們的游戲現(xiàn)在已經(jīng)完成,并且我們可以跟據(jù)實(shí)際情況來判定玩家的輸贏,但我們應(yīng)該再給它添加一個(gè)關(guān)鍵功能:處理以前猜到的字母。每當(dāng)玩家猜到前一個(gè)字母,他們不應(yīng)該為此受罰,但他們也應(yīng)該能夠看以前的猜測。在該項(xiàng)目的開始,我們創(chuàng)建了一個(gè)變量guessed,到現(xiàn)在為止我們還沒有使用過這一變量。該變量一直為空列表,因此 到目前為止,讓我們實(shí)現(xiàn)它。在我們添加到列表之前,請確保我們可以打印出正確的信息:

          16|  hidden_word = ???
          17|  print("Your guessed letters: {}".format(guessed) )
          18|  print("Word to guess ???

          繼續(xù)并運(yùn)行這一代碼塊。在我們輸出信息的頂部,打印出猜字母的完整列表。最好將其保留在列表中。即使您猜到了,它仍然會顯示一個(gè)空列表,因?yàn)槲覀冞€沒有為它添加功能呢。

          增加玩家猜測的字母

          現(xiàn)在,我們添加功能來將玩家猜測的字母添加到我們的變量guessed列表中:

          37|  print("Incorrect, ???
          39|  if ans not in guessed:
          40|   guessed.append(ans) # 增加元素到guessed列表
          42|   if lives <= 0: ???

          繼續(xù)并運(yùn)行這一代碼塊?,F(xiàn)在guesses列表將隨著玩家玩游戲而更新。

          處理以前的猜測

          最后一項(xiàng)業(yè)務(wù)是確保當(dāng)他們再次猜出同一字母時(shí),程序并沒減少玩家的生命值,而是提醒他們被猜到了。我們需要重寫整個(gè)條件語句,以檢查字母是否在整個(gè)詞語中:

          27|   game_over = True ???
          28|  elif ans in word and ans not in guessed:
          29|   print("You guessed correctly!") ???
          34|   guesses[ i ] = ans ???
          35|  elif ans in guessed:
          36|   print("You already guessed that. Try again.")
          37|  else: ???

          繼續(xù)并運(yùn)行這一代碼塊。我們必須更改第28行的elif語句,因?yàn)槲覀冞€需要檢查該字母是否尚未添加到猜測列表中。在第35行,我們添加了第二個(gè)elif語句,該語句將檢查字母是否特別在變量guessed列表中清單。請記住,一旦運(yùn)行一個(gè)if/elif語句,那么它下面的語句將不會運(yùn)行。如果這些條件都不是真的,那意味著他們還沒猜到字母,它不在隨機(jī)詞語中。到這里,游戲現(xiàn)已全部完成,并具有非常完整的功能。

          寫在本周最后的話

          恭喜你,完成此項(xiàng)目!由于項(xiàng)目大小,完整代碼不會寫在這里。相反,你可能會在以下位置找到完整的代碼版本,本書的資源文件位于Github上。您可以在書的最前面找到相應(yīng)的鏈接,每周的所有資源文件都位于該鏈接內(nèi)。查找具體該項(xiàng)目的代碼,只需打開或下載“ Week_04.ipynb”文件。如果遇錯(cuò)誤,請確保將你的代碼與該文件中的代碼交叉引用,并且查看你可能出現(xiàn)的問題。所有未來項(xiàng)目的最終代碼輸出也可以在同一位置找到,因此請務(wù)必在此頁面添加書簽。


          多么美好的一天!我們能夠使用循環(huán)的概念以及列表來創(chuàng)建一個(gè)有趣的游戲。嘗試添加自己的代碼,或?qū)⑵渲貥?gòu),以更進(jìn)一步了解,什么可能會或可能不會。


          一周總結(jié)

          當(dāng)然,這是其中較長的一周,每天都充滿了大量的信息。請自己務(wù)必花一些時(shí)間對這些概念進(jìn)行練習(xí)或通過完成每天的練習(xí)來實(shí)踐這些概念。我們介紹了為什么列表在Python中如此重要以及如何在我們的程序中使用它們。還介紹了Python提供的兩個(gè)循環(huán):for循環(huán)和while循環(huán)。使用循環(huán),我們可以根據(jù)需要多次重新運(yùn)行代碼,或?qū)ο窳斜磉@樣的數(shù)據(jù)集合進(jìn)行迭代。如果你對這些信息不知所措,請確保在剩余的部分,我們在所做的所有事情中都使用循環(huán)和列表。這會給你很多練習(xí)和重復(fù)。

          歡迎點(diǎn)擊閱讀原文訪問 我的Python中文網(wǎng),學(xué)習(xí)更多Python教程。

          瀏覽 121
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  高清国产视频在线观看 | 中文字幕日韩在线观看 | 亚洲国产日韩在线 | 久久久久亚洲AV无码麻豆 | 亚洲天堂在线观看网站 |