老婆最喜歡玩縱橫字謎,比如對南方周末每期的《小強填字》總是津津樂道。最近我閑來無事,不妨做一個電腦上玩的填字,以博老婆一笑,^-^。
首先應該有一個TPuzzleItem類吧?這個表示謎題的單個條目,包括座標、方向(橫向還是縱向)、謎面、謎底等屬性,對了,還應該儲存解題人輸入的答案。這個TPuzzleItem還應該有一些方法(沒有方法的類,也就沒有存在的必要了),比較重要的就是根據給定的邏輯座標返回該儲存格的字元(如果給定的座標不屬於該條目,就返回空),為了便於匯入和匯出,還應該有ExportToXMLNode和ImportFromXMLNode這兩個方法,以便於根據XML節點來匯入匯出。
多個條目應該由TPuzzle類來管理,TPuzzle有一個私人的TList對象來維護條目列表,而不是讓TPuzzle從TCollection繼承,因為我實在不想過多去瞭解這個TCollection的內部結構,用委託而不是繼承,也是俺一貫的做法。同樣,TPuzzle也應該有ExportToXMLNode和ImportFromXMLNode這兩個方法。每一個TPuzzle代表一個謎題,為了區分不同的謎題,它具有一個Guid屬性。
TPuzzle與TPuzzleItem於GUI完全無關,它只是在提供謎題的邏輯,至於介面上如何?,如何與使用者互動這些工作,交給TPuzzleGUI來處理。TPuzzleGUI委託一個私人欄位FPuzzle來處理邏輯方面的問題,自己接受使用者的輸入、負責在螢幕上繪製出謎題。TPuzzleGUI從TCustomControl繼承,並具有WS_VSCROLLBAR和WS_HSCROLLBAR屬性,這樣可以顯示很大的柵格給使用者(雖然實際上可以用不到),由於並未對柵格建立二維數組,只是由TPuzzle來維護一組條目列表,所以佔用的記憶體並不因螢幕上顯示的柵格多少而增加。
介面的設計可簡可繁,反正一切都是繪製出來的,由於繪製的小地方比較多,所以TPuzzleGUI也用一個緩衝區,先將所有要繪製的內容畫在緩衝區中,再一次性畫上螢幕,有點象DirectDraw的做法,但是這種小玩意就不用勞DX的大駕了吧。介面設計稍微細微一點,帶給使用者的感覺也就好一點,可惜俺不是美工,沒辦法把一切都畫得那麼完美:-(
還剩下一個如何儲存多個謎題的問題,這種儲存由TPuzzleContainer來完成,這是一個抽象類別,才能方便俺以後改變儲存方式,比方說今天用XML來儲存,明天想通了,或許就用個ACCESS庫了呢。抽象原廠模式應該是要用到的吧,雖然現在還看不出有什麼好處,呵呵。