極客戰記的關卡主要是偏向鍛煉用戶的基本語法結構和計算機思維,讓大家熟悉極客戰記的操作與代碼的使用。“似曾相似的味道”這關涉及的知識點較多,有字符串的連接,程序的自動化邏輯,還有運算符的使用,利用變量和字符串的連接,實現了循環自動讓英雄唱歌的程序,合理利用變量和循環,能讓你的程序更具備自動性。
1. 思路講解
查看默認代碼,在代碼里能看到一大段的英文,給人一種沒有翻譯完全的恐怖感,但實際上閱讀注釋就會知道,這一大段的英文,只是英雄需要唱的英文歌謠,我們不需要理解它的意思。
如果此時注釋閱讀完了,但仍不太清楚本關的任務,還可以直接運行游戲,看看默認代碼的運行情況及失敗原因。從左上角可以看到,本關的過關目標是讓英雄跟著大家一起唱歌。
但是從實際的運行情況來看,除了第一句“ 10 potions of health on the wall!”以外,英雄唱的都跟別人不一樣。因此我們可以按照注釋和游戲動畫里的模板,為英雄添加代碼,讓英雄唱的內容跟其他人一樣。從頭開始查看動畫,觀察大塊頭的歌唱內容:
10 potions of health on the wall!
10 potions of health!
Take 1 down, pass it around!
9 potions of health on the wall!
9 potions of health on the wall!
9 potions of health!
Take 1 down, pass it around!
8 potions of health on the wall!
8 potions of health on the wall!
……
可以看出歌唱的內容似乎具有一定的重復性。再看看注釋給的歌唱模板。
如果把X當成10,Y當成1,就會發現這四句注釋的內容恰好與前四句歌唱內容一模一樣。然后再把X當成9,Y當成1,則又變成了接下來的四句。因此我們可以分析出,歌唱內容具有一個循環性,每四句一個循環,可以直接使用循環來讓英雄唱歌,減輕代碼量。但如果要使用循環又會有一個問題,循環的內容都是設定好的,但實際的歌唱內容,每四句X就會減1,那么這個又該如何實現呢?
還記得在地牢里我們是怎么實現全自動發現敵人攻擊敵人的嗎?
while True:
enemy = hero.findNearestEnemy()
if enemy:
hero.attack(enemy)
利用變量,我們隨時發現新的敵人,將它的名字賦入變量里,再讓英雄對這個變量發起進攻,這樣就用一個變量,實現了發現敵人,攻擊敵人,再發現新敵人,再攻擊新敵人的程序邏輯。
因此,如果我們想要實現全自動的循環唱歌,我們也可以利用變量。其實注釋里的模板就是給我們最大的提示,模板里的X和Y兩個未知數,不正是我們需要設置變量的兩個內容嗎?
前兩句唱的是X,第三句唱Y,而第四句就是唱X-Y,唱完四句,再讓X變量減1,Y不變,開始下一個循環。明白了過關思路后,那么我們就可以開始動手寫代碼了。此時或許會有一個問題,變量如何和字符串混用?
2.字符串連接
以往我們說話,輸出字符串,有兩個方式:(1)直接輸出型;(2)變量間接輸出型。從來沒有試過變量和字符串同時混用的,你不能把變量加到雙引號內,這樣它就變成了一個普通的字符,也不能放在雙引號外,直接混用會發生報錯。
此時我們就需要使用加號連接符「+」,當我們需要將變量和字符串同時輸出的時候,我們就需要將加號連接符「+」放在兩個內容的中間,就像這樣:
此時報錯就解除了,英雄也能準確說出要說的內容。明白了使用方法后,即可開始編寫過關代碼。系統已為我們定義好兩個變量,根據第11行的歌唱內容,我們也能分析出potionsOnTheWall對應的正是X,numToTakeDown對應的是Y。因此我們可以補出后面的代碼:
連接的時候,可千萬別忘了用于美觀的空格。寫到第16行的時候,你看到了一行陌生的代碼,如果你不知道它的作用,可以先將它刪去,然后按照自己的思路進行過關,一會兒我們再對這行代碼進行講解。寫上最后一句,這時,循環的前四句要歌唱的內容已經寫好,接下來如果要進入下一句循環,我們需要將X,也就是potionsOnTheWall減1。這樣,我們就可以順利通關了。
但這還并不是完美的通關代碼,根據歌謠的內容,其實每一次X減去的數值都是Y的數值,而Y剛好是1,因此我們最后一行就可以直接寫X - 1,但這仍然并不完美,因為如果Y的數值改變了,那么我們還要手動更改最后一行的數值,所以我們還可以對代碼做一定的修改。
3.自增自減運算
看到最后一行代碼,我們在這一行里,進行了一個減法的運算,讓potionsOnTheWall的值等于potionsOnTheWall - 1,這就是一個自減的運算。
比如potionsOnTheWall = potionsOnTheWall - 1,因為在代碼中,像加減乘除這一類運算式是優先計算的,所以這一行的代碼,會先執行potionsOnTheWall - 1 ,然后得出結果,當potionsOnTheWall為10時,這里的結果就會是9。
然后再執行賦值運算「=」,用等號,將結果賦入potionsOnTheWall變量中,這樣就實現了potionsOnTheWall變量的自我減少。由于1和變量numToTakeDown的值是一樣的,為了實現更方便的代碼,讓每次potionsOnTheWall都減去的是numToTakeDown的值而不是我們手動設定的值,我們可以把此處的1,替換成numToTakeDown。
就像這樣,效果也是一樣的,而這種自減運算,還有一種縮寫形式:直接把減號、等號,還有重復的內容省去,這也就是我們剛剛刪除掉的代碼了。它的作用,就是將potionsOnTheWall自減去numToTakeDown的值,同理也還有自增語句。因此我們可以對代碼結構優化一下,在最后一句歌詞前,先進行一次自減,然后potionsOnTheWall的值就減少了1,就可以直接在最后一句歌詞里使用potionsOnTheWall變量了。此時的代碼,就更為靈活精簡了。