哈工大2020春軟件構造實驗2
Problem 3 Playing Chess 架構設計思路
- 問題簡述
- 整體結構
- ADT功能設計
- 功能實現路徑
問題簡述:
- 設計一款棋類遊戲,同時支持國際象棋(Chess)和圍棋(Go)
- 實現功能
- 選擇遊戲類型:創建Game、Board
- 輸入玩家名字:創建Player、Piece,其中Piece屬於Player
- 開始遊戲,輪流選擇功能
- 放棋:給定player、piece、x、y
- 移動棋(chess):給定player、piece、x1、y1、x2、y2
- 提子(go):給定player、x、y
- 喫子(chess):給定player、x1、y1、x2、y2
- 查詢某個位置佔用情況:給定x、y
- 計算兩個玩家分別的棋子總數
- 跳過
- 結束:輸入“end”
- 結束並輸入玩家所有步驟
整體架構
- 箭頭表示支配
- 下文仔細闡述各個ADT的作用以及之間關係
- 在支配關係中,雙方均可以互相通過方法訪問,下文不再說明
ADT功能設計
MyChessAndGoGame.main()
- 需要給出交互界面
- 依據用戶的輸入來選擇功能
Game
- One Game should be an OBJECT.
- 目前我將Game設計爲interface(有重構計劃)
- Game有兩個類接入:
chessGame
和goGame
- 爲了使客戶端調用清晰方便,我將每一個功能設計爲一個Game的method
關係
- Game支配Board和Player
- Game受main()支配
Player
- Player被Game支配,是因爲在流程中在其之後新建,也因爲意義上的符合
- Player擁有Piece,因此在新建Player時就應該賦予其Piece
- chess中需要將每個Piece初始化Position
- go則只需要將Piece放入成員變量
Set<Piece> pieces
中 - 由於在Player屬於Game,因此Game是Piece的generator
- 我認爲Board和Player不需要關聯,這也一定程度上相互保護
關係
- Player支配Piece和Action
- Player受Game支配
- Player和Board、Position無直接聯繫
Board
- Board在chess和go中高度相似,主要區別在邊長,所以我認爲沒必要設計interface
- 由於Game接口已經分出了兩個類,因此可以兩個類分別爲Board加上屬性
- 在創建Game時即可創建Board
- Board擁有N*N個已經初始化的Position對象,在構造函數中實現
- 由於Board擁有的是對象,則Position的更改能在Board中自動更新,因此Action操作時不需要更改Board和Player
關係
- Board支配Position
- Board受Game支配
- Board與Player、Piece、Action無直接聯繫
Piece
- Piece與Position捆綁,一方的更新必然引起另一方的更新,但不是一一對應
- Piece屬於Player,但是Player不能直接影響Piece,只能查詢
- 能影響Piece的是Action
- 這裏的設計可以是Action影響Piece或者Position,我選擇了後者
- 因此,Player通過Action,Action再通過Position影響了Piece
- Piece的更迭本質上定義爲“Position的更迭”,同理Position的更迭本質上定義爲“Piece的更迭”
關係
- Piece與Position相互支配
- 此外Piece只受Player支配
Position
- Position的特性在我的設計中幾乎和Piece形影不離
- 初始化除外,Position的更改只源於Action
- Position和Piece一定同步更新
關係
- Position與Piece相互支配
- 此外Position屬於Board,並受Action支配
Action
- Action是一個接口,引申出
goAction
和chessAction
兩個類 - Action將put(放棋)、move(移動棋)和capture(喫子/提子)融合在一起
- 每當Player新建一個Action,便立刻依據參數執行相應類型的action
- 這樣的設計簡化了外部的代碼,以參數和內部方法冗餘作爲代價
個人認爲還算是一個比較巧妙的設計
- Action的方法包括了4種操作,通過重寫可以在特定的game type中壓縮方法數量
- 每次的Action被記錄在Player對象下的
actions
中
關係
- Action支配Position
- Action受Player支配
功能實現路徑
- 設計中每個功能的實現在類之間的使用情況
main()只存儲
Game
和Player
選擇遊戲類型
- 實現
new Game()
- 在
Game()
中實現new Board()
- 在
Board()
中實現new Position
(這裏需要重寫)
創建玩家
- 實現
new Player()
- 在
Player()
中調用Game()
中生成Piece的方法實現new Piece()
Piece()
生成時查詢相應Position(Player --> Game --> Board --> Position)
放棋put、移動棋move、喫子/提子capture
- 在Player對象中
new Action()
- 在
new Action()
通過參數直接實現相應功能
查詢佔用isFree
- 通過
Game --> Board --> Position
,詢問Position的佔用情況
計算雙方棋子數sumPiece
- 通過
Player
中的方法,計算成員變量Set<Piece>
的.size()
- 返回
Map<Player, Integer>