這是這個課件的一部分: 現代程序設計 (課程設計中, 征求意見稿)
好多同學們都說題目難,這回我們來一個簡單而很有意義的。 :)
寫代碼爽還是讀代碼爽? 往一堆亂麻中再加上一些線索,似乎比較容易;然而從這一團亂麻中理出頭緒,還是比較難的。下圖來自 知乎的一個討論。
我們練習了這么多作業,所有作業都是從頭寫程序,但是我們到了真正的項目組或公司里,通常我們會改進一個已經存在項目 (這個項目說不定已經存在好多年了),這個項目的文檔也不多,編碼規范也不是太完美。 這時候我們怎么辦? 我們當然可以通過下面的辦法:
- 理解程序
- 在不損害程序現有功能的情況下,修復bug 或增加新功能
- 同時有計划地通過重構或重寫,改進這個程序,讓它更好地被程序員理解,更好地能適應可能產生的變化。
這個作業就是這樣一個例子。
假設有一組水平不高的程序員,或者一個水平不高的程序員(比如我),在很久以前為了學習Java, 就寫了一個 Java 的圍棋下棋程序 (不是人工智能,只是在屏幕上展現下棋的過程), 后來C# 出現之后,他又隨意地把程序改寫為C#, 經過簡單測試之后,他就把程序放在一邊了。
現在我們拿到了這個代碼,程序還可以編譯成功,但是不巧的是一個關鍵函數只有函數體,沒有具體的實現了。例如:
int GetLiberty(int x, int y, StoneColor c ) //判斷當前的位置上的棋子和相連的一組棋子一共有多少氣
這個程序原來總共有30行(算上空行和單字符行),但是由於種種原因, 這個函數只剩下了一句話
return 1;
現在請用遞歸和非遞歸兩種方式把它實現出來。
關於個棋子或一組相連的棋子有多少氣,有沒有氣, 十分簡單。
詳細的規則請看網上的許多教程。 舉兩個非常簡單的例子:
如果此時該黑棋下,黑棋下在 (A,1) 的位置, 那么黑棋就把白棋 A2 的棋子吃掉了。如果此時該白旗下,白棋下在 C1 的位置,那么白棋就把兩顆黑棋吃掉了。
此時,黑白雙方誰能占據 O4 的位置, 就能夠決定兩個黑棋有沒有氣。
(上面的題目已經在課堂上搞定了,我們再擴展一下)
目前給同學們的程序能在下面兩種情況下瀏覽棋局:
a) 直接在棋盤上面點擊,程序就會按照黑白相間的次序走棋。
b) 用戶可以用程序打開一個棋譜文件 (*.sgf), 然后按 “>” 按鈕,程序就會按次序下棋。
大家注意到用戶界面上還有一個 “<” 按鈕, 這是讓用戶把下棋的步驟倒回去 (如果上一步一方吃掉了許多棋子, 那么我們還要把這些吃掉的棋子恢復好)
函數說明在這里:
這個函數的大部分都沒有實現,現在我們要實現它。 (要求: 所有的修改都只在這一個函數體里面)
我們的同學們學了《現代程序設計》,搞定下面的挑戰應該不成問題:
1) 把程序編譯通過, 跑起來。
讀懂程序,在你覺得比較難懂的地方加上一些注釋,這樣大家就能比較容易地了解這些程序在干什么。
把正確的 playPrev(GoMove) 的方法給實現了。 如果大家不會下圍棋,那就需要大家實地或者上網練習一下圍棋的死活,提子是怎么回事。這個應該一個小時就能搞定。
2)根據你選擇的教材 (三本之一或更多),點評一下這個程序設計方面的不足,例如:
編碼風格,
程序架構,有哪些不符合良好的設計,這個程序的設計模式 (MVC等) 是高端大氣國際化的么? 等等。
程序的錯誤處理,文件處理,UI 等等
大家可能會想到,這個程序雖然說編譯都過了,但說不定有很多基本的小問題沒解決,VS 的強大的編譯器和代碼分析工具能把它們都找出來? 當然可以:
大家可以運行 VS 的代碼分析工具,找到這個程序的這些問題,並改進。下面是報告的一部分:
這些改進可以是很小的,例如,把所有函數的命名都規范化,這算一個改進。同學們至少要把Code Analysis 報告的所有問題給解決了。
關於Code Analysis 的更多信息:
http://msdn.microsoft.com/en-us/library/ee1hzekz.aspx
http://msdn.microsoft.com/zh-cn/library/vstudio/ms182278.aspx
3) 程序的注釋
所有人都覺得注釋很重要,寫程序不寫注釋的同學真是RP 比較低。。。
那么,就請把這個程序中被標成 “zzzz” 的注釋都恢復過來。 當然,你可以用中文寫注釋。
4) 選擇題: (提示: 這個題目另外算分,滿分10分,需要掙分的同學就可以考慮這個選擇題)
對於功能上的小問題, 那么你怎么改進呢? 請選出 1-2個你想做的改進,然后運用你的各種編程技術和能力把這些改進給實現了(必須明確指出改進/增加了哪一個功能)。
把所有的改進都實現之后,把代碼簽入 GitHub, 經歷了這一番改動,你的程序和別的同學的程序就很不一樣了。
如果大家有時間並有興趣,可以做一些大的改進:
a) 如果我要把這個程序變成一個可以人機對戰的小游戲 (假設你的AI 模塊已經寫好,這里我們就可以讓一個函數返回一個合法的位置就可以), 那這個程序的架構應該怎么變化? 請把這個功能寫出來。
b) 如果我想讓這個程序變成兩個用戶可以通過網絡對戰,這個程序的架構要怎么變化?
另: 大家在讀程序的時候可以測試一下自己的會發什么樣的腦電波。 :) 看看下面的論文:
http://wwwiti.cs.uni-magdeburg.de/~feigensp/experiments/fMRI/fse_fMRI-Poster.pdf