软件构造 Lab2

本次实验聚焦抽象数据类型(ADT)的设计、规约、测试与实现,运用面向对象编程技术。涵盖git仓库操作、Graph类及相关子类的实现与泛型化,还包括GraphPoet的实现与测试。此外,使用实现的Graph重写社交网络任务,设计并实现了下棋游戏的ADT及主程序,同时介绍了测试方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验目标:
本次实验训练抽象数据类型(ADT)的设计、规约、测试,并使用面向对象
编程(OOP)技术实现 ADT。具体来说:
⚫ 针对给定的应用问题,从问题描述中识别所需的 ADT;
⚫ 设计 ADT 规约(pre-condition、post-condition)并评估规约的质量;
⚫ 根据 ADT 的规约设计测试用例;
⚫ ADT 的泛型化;
⚫ 根据规约设计 ADT 的多种不同的实现;针对每种实现,设计其表示
(representation)、表示不变性(rep invariant)、抽象过程(abstraction
function)
⚫ 使用 OOP 实现 ADT,并判定表示不变性是否违反、各实现是否存在表
示泄露(rep exposure);
⚫ 测试 ADT 的实现并评估测试的覆盖度;
⚫ 使用 ADT 及其实现,为应用问题开发程序;
⚫ 在测试代码中,能够写出 testing strategy 并据此设计测试用例。

实验任务:

Get the code and prepare Git repository
git仓库代码:
git init 创建仓库
git add * 添加仓库文件
git commit -m “lab2” 添加信息
git remote add origin url 添加远程库信息
git push -u origin master 上传内容

Poetic Walks

Test Graph
本问要完成测试,只需修改graph中的构造函数就可以完成测试。
在这里插入图片描述
改为生成子类即可。

Implement Graph
Implement ConcreteEdgesGraph
本小问在于实现ConcreteEdgesGraph类。
在这里插入图片描述
题目给了我们点的集合和边的列表,储存各自信息,我们只要实现接口函数即可。
先实现边类
在这里插入图片描述
有以下三个内部属性:头节点、尾节点、权重,组成。
之后,主类有如下六个函数特别需要实现:
1、添加点
在这里插入图片描述
2、设置边
在这里插入图片描述
3、从点集合中删去点
在这里插入图片描述
4、获取点集合
在这里插入图片描述
5、获取某点连接的下一节点的Map
在这里插入图片描述
6、获取某点连接的上一节点的Map
在这里插入图片描述

Implement ConcreteVerticesGraph
本小问要求实现ConcreteVerticesGraph类,同样是实现接口函数,只不过这次只给了边的列表。
在这里插入图片描述
本次的节点类内部属性如下:
在这里插入图片描述
由一个标志量和两个分别用于查找上一节点和下一节点的Map组成。
函数具体实现与上一问大同小异,略去。

Implement generic Graph
本问要求将String类型的输入参数改为泛型编程。
首先,在Graph类下,类声明处为Graph:
在这里插入图片描述
将Graph类中的需要修改为泛型的String类型变量都改为L泛型即可完成本问。

Make the implementations generic
同上,要求改为泛型编程。
将ConcreteEdgesGraph类的声明改为ConcreteEdgesGraph,
ConcreteVerticesGraph类也进行如上操作。
在这里插入图片描述
在这里插入图片描述
之后,将两个类中的需要修改为泛型的String类型变量都改为L泛型即可完成本问。

Implement Graph.empty()
实现Graph.empty()函数
代码如下:
在这里插入图片描述
这里生成ConcreteEdgesGraph类,以进行之后的test和GraphPoet。

Poetic walks
Test GraphPoet
本问要求写出测试。
在这里插入图片描述
我这里的测试采用mit网页上提供的测试样例,该样例可以检验编写的GraphPoet的大部分功能。

Implement GraphPoet
本问要求实现GraphPoet。
有以下两个函数需要实现:
1、读取模板
使用FileInputStream进行文件读取。
在这里插入图片描述
实现的思路是读取所有文本内容后,将文本分割成单词,把单词使用P1中实现的Graph来保存下来,weight就是两个单词连接的次数。

2、按模板补全诗
在这里插入图片描述
实现的思路是读取输入的内容,进行分割,按顺序与模板中的词进行以下匹配:若前后两个输入的词都在模板中,且夹着某个词,就将所夹的词填入内容中;若这样的词有多个,则选择weight最大的一个填入。按照这个思路,即可进行诗的补全。

Graph poetry slam
本小问实现main函数。
在这里插入图片描述
main函数与mit提供的模板。

2、Re-implement the Social Network in Lab1
本任务是要使用P1中实现的Graph来重写Lab1的任务。

FriendshipGraph类
具体实现的代码如下:
在这里插入图片描述
FriendshipGraph类此处继承ConcreteEdgesGraph类,泛型此处应用为Person类。
大部分需要的功能在ConcreteEdgesGraph类中都实现了,我们只要添加getDistance的函数即可。
这里使用BFS,搜索到第一个与目标相同的对象时走的距离即是Distance,返回即可。
若未找到就返回-1以提示错误。

Person类
Person类里我只给了两个属性:

String name;
int dis;

name用于辨识不同的Person。
dis方便BFS搜索。

客户端main()
main函数使用Lab1中案例。
在这里插入图片描述
将添加点的函数改为add,添加边的函数改为set,权重设置为1即可。

测试用例

此处我的测试用例选用的是Lab1的测试用例,与上一小问的情况相似,只要修改添加点的函数和添加边的函数即可。在这里插入图片描述

测试用例覆盖了除了main函数外的绝大部分的代码。在这里插入图片描述

3、Playing Chess
ADT设计/实现方案
Ⅰ、接口:
此处我设计了两个接口:
Piece 和 Action。
Piece接口负责棋子的操作,有以下三个:放置到目标位置,获取潜在的有效位置,获取操控者。具体的传入参数和返回值信息见以下代码:
在这里插入图片描述
(补充说明:放置到目标位置需要获取潜在有效位置来确认目标位置是否合法)
Action接口负责Player的操作,有以下四个:放置新棋子(用于围棋)、移动棋子(用于国际象棋)、查询目标位置信息、输出双方棋子数。具体的传入参数和返回值见以下代码。
在这里插入图片描述
设计了哪些ADT(接口、类),各自的rep和实现,各自的mutability/ immutability说明、AF、RI、safety from rep exposure。
必要时请使用UML class diagram(请自学)描述你设计的各ADT间的关系。

Ⅱ、类
一、Position,位置类
内部存储位置坐标信息(横坐标、纵坐标值)与该位置棋子信息以及所属棋盘信息。
在这里插入图片描述

二、Board,棋盘类
内部存储Position的二维数组和棋盘规模信息。
在这里插入图片描述

三、设计两个棋子的大类,实现Piece接口。
1、GoPiece,为围棋的棋子类
围棋判断是否是潜在目标位置的方法是:遍历一遍棋盘上所有的位置,若某个位置没有被占用,则是潜在目标位置。
下子之后调用checkRep函数,查询所下位置上下左右四个位置,若四个位置有对方棋子被包围,则提子。
提子函数是将棋子信息从对应Position中抹除,对应Position回到未被占用状态。

2、ChessPiece,为国际象棋的棋子类
该类为不同类型的棋子的父类,只实现下子函数,而没有实现获取潜在的有效位置的函数。具体的潜在位置获取的实现交给子类。
该类负责实现下子、吃子函数,吃子函数的实现方法是目标抹除目标位置的棋子信息,改为自己。
子类:
①Pawn: 兵,直走斜吃的三个位置是潜在目标位置。
②Rook: 车,直走不越子的所有位置是潜在位置。
③Knight: 马,日字格的至多八个位置是潜在位置。
④Bishop: 相/主教, 斜走不越子的所有位置是潜在位置。
⑤Queen: 后, 直走斜走不越子的所有位置是潜在位置。
⑥King: 王,直走斜走一格内违背占有的位置是潜在位置。
如此就实现了国际象棋的所有棋子类。

四、Player类实现Action接口:
1、放置新棋子:生成一个新的围棋棋子,调用其放置函数放置到目标位置。
2、移动棋子:选取初始位置的棋子,调用其放置函数放置到目标位置。
3、查询目标位置信息:输出目标位置坐标、占有棋子类型、操控者信息。
4、输出双方棋子数:遍历棋盘上所有位置,统计双方棋子个数并输出。

五、MyChessAndGoGame类
用于实现控制台交互,并实现main函数。
在这里插入图片描述

主程序MyChessAndGoGame设计/实现方案
MyChessAndGoGame是游戏主程序类。
在这里插入图片描述
在创建该类时,就同时创建了两位玩家、国际象棋或围棋的棋盘,并若是国际象棋,还将按规则摆放上棋子。即,创建该类时就完成所有的初始化设置。

类函数,角色操纵函数。
在这里插入图片描述
传入参数为某一个玩家以及当前的游戏模式(国际象棋/围棋),根据相应规则,输出提示信息,并读取玩家输入的命令。
在这里插入图片描述
读取命令之后,分割命令,根据第一个单词,来确定具体是哪个操作。并辅以后续参数,完成操作。

main函数只负责创建该类,之后运行时,不断切换角色执行以上操作函数,实现游戏的进行,直到一方提出end,结束游戏。

具体操作截图:
在这里插入图片描述

ADT和主程序的测试方案
介绍针对各ADT的各方法的测试方案和testing strategy。
介绍你如何对该应用进行测试用例的设计,以及具体的测试过程。

测试方案:
我的测试方案是在后台分别模拟一次国际象棋和围棋游戏。
在这里插入图片描述
在这里插入图片描述
考虑各类场景,主要是对棋子下子的测试:
包括:正常下子到空位置,下子后提子(围棋),下子后吃子(国际象棋),企图下子超出棋盘,企图下子到棋盘中的非法位置等情况;以及玩家的下子、移动、查点、查数四个操作。

最后的测试覆盖了除了负责游戏进行的MyChessAndGoGame类以外的绝大部分内容。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值