哈工大软件构造Lab2 Problem3 Playing Chess 架构设计思路
哈工大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>