# 練習45.你來制作一個游戲
你要開始學會自食其力了。通過閱讀這本書你應該已經學到了一點,那就是你需要的所有的信息網上都有,你只要去搜索就能找到。唯一困擾你的就是如何使用正確的詞匯進行搜索。學到現在,你在挑選搜索關鍵字方面應該已經有些感覺了。現在已經是時候了,你需要嘗試寫一個大的項目,并讓它運行起來。
以下是你的需求:
> 1. 制作一個截然不同的游戲。
> 1. 使用多個文件,并使用`import`調用這些文件。確認自己知道`import` 的用法。
> 1. 對于每個房間使用一個 class,class 的命名要能體現出它的用處(例如 `GoldRoom`、`KoiPondRoom`)。
> 1. 你的執行器代碼應該了解這些房間,所以創建一個類來調用并且記錄這些房間。有很多種方法可以達到這個目的,不過你可以考慮讓每個房間返回下一個房間,或者設置一個變量,讓它指定下一個房間是什么。
其他的事情就全靠你了。花一個星期完成這件任務,做一個你能做出來的最好的游戲。使用你學過的任何東西(類,函數,字典,列表……)來改進你的程序。這節課的目的是教你如何構建 class 出來,而這些 class 又能調用到其它 Python 文件中的 class。
我不會詳細地告訴你告訴你怎樣做,你需要自己完成。試著下手吧,編程就是解決問題的過程,這就意味著你要嘗試各種可能性,進行實驗,經歷失敗,然后丟掉你做出來的東西重頭開始。當你被某個問題卡住的時候,你可以向別人尋求幫助,并把你的代碼貼出來給他們看。如果有人刻薄你,別理他們,你只要集中精力在幫你的人身上就可以了。持續修改和清理你的代碼,直到它完整可執行為止,然后再研究一下看它還能不能被改進。
祝你好運,下個星期你做出游戲后我們再見。
## 評估你的游戲
這節練習的目的是檢查評估你的游戲。也許你只完成了一半,卡在那里沒有進行下去,也許你勉強做出來了。不管怎樣,我們將串一下你應該弄懂的一些東西,并確認你的游戲里有使用到它們。我們將學習如何用正確的格式構建 class,使用 class 的一些通用習慣,另外還有很多的“書本知識”讓你學習。
為什么我會讓你先行嘗試,然后才告訴你正確的做法呢?因為從現在開始你要學會“自給自足”,以前是我牽著你前行,以后就得靠你自己了。后面的習題我只會告訴你你的任務,你需要自己去完成,在你完成后我再告訴你如何可以改進你的作業。
一開始你會覺得很困難并且很不習慣,但只要堅持下去,你就會培養出自己解決問題的能力。你還會找出創新的方法解決問題,這比從課本中拷貝解決方案強多了。
## 函數的風格
以前我教過的怎樣寫好函數的方法一樣是適用的,不過這里要添加幾條:
> - 由于各種各樣的原因,程序員將 class (類)里邊的函數稱作 method (方法)。很大程度上這只是個市場策略(用來推銷 OOP),不過如果你把它們稱作“函數”的話,是會有啰嗦的人跳出來糾正你的。如果你覺得他們太煩了,你可以告訴他們從數學方面演示一下“函數”和“方法”究竟有什么不同,這樣他們會很快閉嘴的。
> - 在你使用 class 的過程中,很大一部分時間是告訴你的 class 如何“做事情”。給這些函數命名的時候,與其命名成一個名詞,不如命名為一個動詞,作為給 class 的一個命令。就和 list 的 pop (拋出)函數一樣,它相當于說:“嘿,列表,把這東西給我 pop 出去。”它的名字不是`remove_from_end_of_list` ,因為即使它的功能的確是這樣,這一串字符也不是一個命令。
> - 讓你的函數保持簡單小巧。由于某些原因,有些人開始學習 class 后就會忘了這一條。
## 類的風格
> - 你的 class 應該使用 “camel case(駝峰式大小寫)”,例如你應該使用 `SuperGoldFactory`而不是`super_gold_factory`。
> - 你的 `__init__`不應該做太多的事情,這會讓 class 變得難以使用。
> - 你的其它函數應該使用 “underscore format(下劃線隔詞)”,所以你可以寫`my_awesome_hair`,而不是 `myawesomehair`或者`MyAwesomeHair`。
> - 用一致的方式組織函數的參數。如果你的 class 需要處理 users、dogs、和 cats,就保持這個次序(特別情況除外)。如果一個函數的參數是`(dog, cat, user)`,另一個的是`(user, cat, dog)` ,這會讓函數使用起來很困難。
> - 不要對全局變量或者來自模組的變量進行重定義或者賦值,讓這些東西自顧自就行了。
> - 不要一根筋式地維持風格一致性,這是思維力底下的妖怪嘍啰做的事情。一致性是好事情,不過愚蠢地跟著別人遵從一些白癡口號是錯誤的行為——這本身就是一種壞的風格。好好為自己著想吧。
> - 永遠永遠都使用`class Name(object)`的方式定義 class,否則你會碰到大麻煩。
## 代碼風格
> - 為了以方便他人閱讀,為自己的代碼字符之間留下一些空白。你將會看到一些很差的程序員,他們寫的代碼還算通順,但字符之間沒有任何空間。這種風格在任何編程語言中都是壞習慣,人的眼睛和大腦會通過空白和垂直對齊的位置來掃描和區隔視覺元素,如果你的代碼里沒有任何空白,這相當于為你的代碼上了迷彩裝。
> - 如果一段代碼你無法朗讀出來,那么這段代碼的可讀性可能就有問題。如你找不到讓某個東西易用的方法,試著也朗讀出來。這樣不僅會逼迫你慢速而且真正仔細閱讀過去,還會幫你找到難讀的段落,從而知道那些代碼的易讀性需要作出改進。
> - 學著模仿別人的風格寫 Python 程序,直到哪天你找到你自己的風格為止。
> - 一旦你有了自己的風格,也別把它太當回事。程序員工作的一部分就是和別人的代碼打交道,有的人審美就是很差。相信我,你的審美某一方面一定也很差,只是你從未意識到而已。
> - 如果你發現有人寫的代碼風格你很喜歡,那就模仿他們的風格。
## 好的注釋
> - 有程序員會告訴你,說你的代碼需要有足夠的可讀性,這樣你就無需寫注釋了。他們會以自己接近官腔的聲音說“所以你永遠都不應該寫代碼注釋。”這些人要么是一些顧問型的人物,如果別人無法使用他們的代碼,就會付更多錢給他們讓他們解決問題。要么他們能力不足,從來沒有跟別人合作過。別理會這些人,好好寫你的注釋。
> - 寫注釋的時候,描述清楚為什么你要這樣做。代碼只會告訴你“這樣實現”,而不會告訴你“為什么要這樣實現”,而后者比前者更重要。
> - 當你為函數寫文檔注釋的時候,記得為別的代碼使用者也寫些東西。你不需要狂寫一大堆,但一兩句話寫寫這個函數的用法還是很有用的。
> - 最后要說的是,雖然注釋是好東西,太多的注釋就不見得是了。而且注釋也是需要維護的,你要盡量讓注釋短小精悍一語中的,如果你對代碼做了更改,記得檢查并更新相關的注釋,確認它們還是正確的。
## 為你的游戲評分
現在我要求你假裝成我,板起臉來,把你的代碼打印出來,然后拿一支紅筆,把代碼中所有的錯誤都標出來。你要充分利用你在本章以及前面學到的知識。等你批改完了,我要求你把所有的錯誤改對。這個過程我需要你多重復幾次,爭取找到更多的可以改進的地方。使用我前面教過的方法,把代碼分解成最細小的單元一一進行分析。
這個練習的目的是訓練你對于細節的關注程度。等你檢查完自己的代碼,再找一段別人的代碼用這種方法檢查一遍。把代碼打印出來,檢查出所有代碼和風格方面的錯誤,然后試著在不改壞別人代碼的前提下把它們修改正確、
這周我要求你的事情就是批改和糾錯,包含你自己的代碼和別人的代碼,再沒有別的了。這節習題難度還是挺大,不過一旦你完成了任務,你學過的東西就會牢牢記在腦中。
- 序言
- 前言
- 簡介
- 0:安裝和準備
- 1:第一個程序
- 2:注釋和“#”井號
- 3:數字和數學計算
- 4:變量和命名
- 5:更多的變量和打印
- 6:字符串和文本
- 7:更多的打印(輸出)
- 8:打印, 打印
- 9:打印, 打印, 打印
- 10:那是什么?
- 11:提問
- 12:提示別人
- 13:參數, 解包, 變量
- 14:提示和傳遞
- 15:讀文件
- 16:讀寫文件
- 17:更多文件操作
- 18:命名, 變量, 代碼, 函數
- 19:函數和變量
- 20:函數和文件
- 21:函數的返回值
- 22:到目前為止你學到了什么?
- 23:閱讀代碼
- 24:更多的練習
- 25:更多更多的練習
- 26:恭喜你,可以進行一次考試了
- 27:記住邏輯
- 28:布爾表達式
- 29:IF 語句
- 30:Else 和 If
- 31:做出決定
- 32:循環和列表
- 33:while循環
- 34:訪問列表元素
- 35:分支和函數
- 36:設計和調試
- 37:復習符號
- 38:列表操作
- 39:字典,可愛的字典
- 40:模塊, 類和對象
- 41:學會說面向對象
- 42:對象、類、以及從屬關系
- 43:基本的面向對象的分析和設計
- 44:繼承Vs.包含
- 45:你來制作一個游戲
- 46:項目骨架
- 47:自動化測試
- 48:更復雜的用戶輸入
- 49:寫代碼語句
- 50:你的第一個網站
- 51:從瀏覽器獲取輸入
- 52:開始你的web游戲
- 來自老程序員的建議
- 下一步
- 附錄A:命令行教程
- 簡介
- 安裝和準備
- 路徑, 文件夾, 名錄 (pwd)
- 如果你迷路了
- 創建一個路徑 (mkdir)
- 改變當前路徑 (cd)
- 列出當前路徑 (ls)
- 刪除路徑 (rmdir)
- 目錄切換(pushd, popd)
- 生成一個空文件(Touch, New-Item)
- 復制文件 (cp)
- 移動文件 (mv)
- 查看文件 (less, MORE)
- 輸出文件 (cat)
- 刪除文件 (rm)
- 退出命令行 (exit)
- 下一步