哈工大软件构造Lab2

1实验目标概述

本次实验训练抽象数据类型(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并据此设计测试用例。

2实验环境配置

在 Eclipse IDE 中安装配置 EclEmma(一个用于统计 JUnit 测试用例的代码覆盖度的 plugin)直接从Eclipse Market下载安装即可。
在这里给出你的GitHub Lab2仓库的URL地址(Lab2-学号)。
https://github.com/ComputerScienceHIT/Lab2-1183710129

3实验过程

3.1Poetic Walks

该任务主要是实验一个图的模块,并基于此使用。
(1)完善Graph接口类,并运用泛型的思想,将String拓展为泛型L类;
(2)实现Graph类的方法:add、set、remove、vertices、sources、targets;
(3)利用实现的Graph类,应用图的思想,实现GraphPoet类,如果输入的文本的两个单词之间存在桥接词,则插入该桥接词;若存在多个单一桥接词,则选取边权重较大者。

3.1.1 Get the code and prepare Git repository从https://github.com/rainywang/Spring2020_HITCS_SC_Lab2/tree/master/P1获取初始代码

Git命令:
git init
git remote add origin git@github.com:ComputerScienceHIT/Lab2-1183710129.git pull origin master
git add .
git commit -m “init”
git push origin master

3.1.2 Problem 1: Test Graph

这部分主要是针对Graph设计测试策略,编写测试用例主要利用等价类划分的思想进行测试,测试策略如下:
在这里插入图片描述
编写覆盖以上条件的测试用例。

3.1.3 Problem 2: Implement Graph

3.1.3.1 Implement ConcreteEdgesGraph

1.实现Edge

Fileds作用
private final L source;起始节点
private final L target;目标节点
private final int weight;边权值
Method作用
public L getsource()返回有向边起始节点
public L gettarget()返回有向边目标节点
public int getweight())返回边权值
public String toString()使用@Override注释toString以确保正确覆盖Object方法的toString方法

2.实现ConcreteEdgeGraph

Method作用
public boolean add(L vertex)调用vertices.add,其返回结果为boolean且满足spec定义。
public int set(L source, L target, int weight)输入source,target,weight,确定一条有向边。具体做法:如weight!=0,移去可能已经存在的边,然后加入新的边,如weight=0.寻找可能已经存在边并删除。
public boolean remove(L vertex)从vertices中删去,传入的参数vertex点,遍历edges,寻找是否有边的起点或者是终点是该vertex,删去。注意在使用迭代器遍历时要使用iterator.remove方法保证安全。
public Set vertices()返回vertices集合
public Map<L, Integer> sources(L target)根据传入的target参数寻找以targe为终点的边。返回一个键值对为(点,权重)的map。
public Map<L, Integer> targets(L source)根据传入的source参数寻找以source为起点的边。实现同上。

在这里插入图片描述
关于AF,RI和rep exposure:
在这里插入图片描述
在这里插入图片描述

3.1.3.2 Implement ConcreteVerticesGraph

1.实现Vertex

Field作用
private final L name节点名字
private final Map<L, Integer>sources = new HashMap<>()所有以name为目标节点的边,<起始节点name,边的权重>.
private final Map<L, Integer>targets = new HashMap<>()所有以name为起始节点的边,<目标节点name,边的权重>
Method作用
public L getname()返回该节点的name
public Map<L, Integer> getsources()根据传入的target参数寻找以targe为终点的边。返回一个键值对为(点,权重)的map。
public Map<L, Integer> gettargets()根据传入的source参数寻找以source为起点的边。实现同上。
public boolean removesource(L source)检查输入满足source!=null,调用sources.remove,并返回(不存在则返回false)。
public boolean removetarget(L target)检查满足target!=null。调用targets.remove(),返回。
public boolean setsource(L source, int weight)检查输入满足source!=null,weight>=0。当weight==0时,调用this.removeSource,当weight>0时,调用Map.put修改source并且记录初始值。
public boolean settarget(L target, int weight)检查输入满足target!=null,weight>=0,当weight=0时,调用this.removeTarget,当weight>0时,调用targets.put并返回(不存在则返回false)。

2.实现ConcreteVerticeGraph

Method作用
public boolean add(L vertex)检查输入满足vertex!=null。遍历点集vertices,若已存在vertex则返回false,否则调vertices.add并返回true
public int set(L source, L target, int weight)遍历点集,分别检查vertices中是否存在source vertex和target vertex,若均不存在则调用vertices.add并调用source.setTarget和target.setSource设置边和权值,
public boolean remove(L vertex)检查输入满足vertex!=null。如果输入节点不存在则返回false,否则,遍历vertices中的每一个节点调用v.remove在targes和sources中删除该节点。
public Set vertices()遍历点集,找到Label与vertex相同的点并加入Set中,最后返回Set。
public Map<L, Integer> sources(L target)遍历点集.如果没有target则返回空集合,否则调用targetVertex.getSources(target)
public Map<L, Integer> targets(L source)遍历点集如果没有target则返回空集合,否则调用sourceVertex.getTargets(source)

关于AF,RI和rep exposure:
在这里插入图片描述
在这里插入图片描述

3.1.4 Problem 3: Implement generic Graph

3.1.4.1 Make the implementations generic

将两个实例类中的所有String类的参数替换为泛型的参数(声明、函数参数、返回值、rep)

3.1.4.2 Implement Graph.empty()

修改Graph.empty为:
在这里插入图片描述
这里以ConcreteEdgesGraph作为Graph默认的实例类,也可以用ConcreteVerticesGraph,二者是等价的
使用Double类进行泛型测试,测试图为:
在这里插入图片描述
测试结果为:
在这里插入图片描述

3.1.5 Problem 4: Poetic walks

3.1.5.1 Test GraphPoet

关于测试策略:
在这里插入图片描述
具体测试:
在这里插入图片描述
在这里插入图片描述

3.1.5.2 Implement GraphPoet
public GraphPoet(File corpus)打开文件,读取文件输入,识别序列,构建图结构。具体:利用BufferedReader.readLine方法读取全部输入后用string.split以空格划分,保存在数组中,随后每次取相邻元素,在图中新增边。
public String poem(String input)还是利用相同方法分割输入字符串,声明一个StringBuilder保存返回结果。每次读取一个词,然后以当前词为source,下一个词为target,在graph中寻找符合此条件的边,记录权值,结束后选择权值最大的,利用StringBuilder. Append方法,将节点名字加入字符串。
public String toString()调用ConcreteEdgesGraph的toString方法,输出图结构

关于AF,RI和rep exposure:
在这里插入图片描述
在这里插入图片描述

3.1.5.3 Graph poetry slam

原始数据是网上的一篇作文。
在这里插入图片描述

3.1.6 Before you’re done

请按照http://web.mit.edu/6.031/www/sp17/psets/ps2/#before_youre_done的说明,检查你的程序。
如何通过Git提交当前版本到GitHub上你的Lab2仓库。
git add .
git commit -m “xxx”
git push -u origin master
在这里给出你的项目的目录结构树状示意图。
在这里插入图片描述

3.2 Re-implement the Social Network in Lab1

继承P1中ConcreteEdgesGraph或者ConcreteVerticesGraph类 实现FriendshipGraph,通过基本操作实现FriendshipGraph中addVertex,addEdge和getDistance三个接口,要求不能修改父类rep。

3.2.1 FriendshipGraph类

将以前的邻接表结构改为新的有向图结构。
声明:
在这里插入图片描述
作为存放person点的有向图,这里采用ConcreteVerticesGraph这一实现,更加符合我们对关注的是每一个“人”的抽象。

Method作用
public boolean addVertex(Person e)遍历父类的vertices(),如果存在一个元素的name域与Person的name域相等,证明这个点已经存在,输出提示,否则调用父类的add(person)将该点加入
public void addEdge(Person p1, Person p2)先调用父类的set(p1,p2,1),如果返回值为0证明这两个点之间不存在边,否则证明这两个点之间已经有边存在,输出提示
public int getDistance(Person p1, Person p2)使用BFS算法求p1与p2之间的最短距离,BFS需要遍历邻居节点时调用父类接口的targets(p1)就可以获得p1的所有邻居节点。
public Setpersons()copy一份vertices,存储图中所有的顶点,即关系网络中的所有人。
public static void main(String[] args)与Lab1相同

3.2.2 Person类

由于继承了ConcreteVerticesGraph,所以可以调用父类的rep和function,因此Person类就不需要过多的修饰。
在这里插入图片描述

3.2.3 客户端main()

Lab1实验手册给出。

3.2.4 测试用例

与Lab1相同。

3.2.5 提交至Git仓库

如何通过Git提交当前版本到GitHub上你的Lab2仓库。
git add .
git commit -m “xxx”
git push -u origin master
在这里给出你的项目的目录结构树状示意图。
在这里插入图片描述

3.3 Playing Chess

3.3.1 ADT设计/实现方案

1.Position(mutable)
在这里插入图片描述

Method作用:
public boolean set(int x, int y)修改位置的横纵坐标
public int getX()public int getY()得到横纵坐标

2.Piece(mutable)
在这里插入图片描述

Method作用:
public String Name()得到棋子的名字
public Color color()得到棋子的颜色
public Piece clone()返回一个与该棋子具有相同属性的不同棋子

3.Player(mutable)
在这里插入图片描述

Method作用:
public String Name()得到玩家的名字
public Color color()得到玩家的颜色
public boolean addpiece(Piece e)该玩家获得一枚棋子
public void addstep(String step)添加一步到该玩家的走棋历史中
public List History()得到该玩家的走棋历史
public Set pieces()得到该玩家所拥有的棋子

4.Board(mutable)
在这里插入图片描述

Method作用:
public int size()得到棋盘的大小
public Piece[][] pieces()得到棋盘上棋子的分布
public void set(Piece piece, Position point)向该棋盘上指定位置上放置一枚棋子
public Piece get(Position s)获得棋盘上某位置的状态

5.Actions(interface)

Method作用:
public boolean CreatePlayer(String name)创造一个不重复的新玩家
public boolean Detach(Position point)移除棋盘上指定位置上的棋子
public Board board();得到棋盘的状态
public boolean Islegal_Position(Position point);判断一个坐标是否在该棋盘上
public void Skip();放弃此回合
public Piece Query(Position s);查询某个位置的占用情况(空闲,或者被某一方的什么棋子所占用)
public int Calculate(Player player);计算玩家在棋盘上的棋子总数
public Player GetPlayer1();返回玩家1的对象
public Player GetPlayer2();返回玩家2的对象

6.InternationalChess(实例类)
在这里插入图片描述
提前初始化国际象棋的棋子
在这里插入图片描述

Method作用:
public boolean Move(Position s, Position t)将s上的棋子移动到t上
private boolean Rule(Piece E, Position s, Position t)判断国际象棋各个兵种行棋的步骤是否符合规则

7.ChineseGo(实例类)
在这里插入图片描述

Method作用:
public boolean Place(Position s)将s上的棋子移动到t上

3.3.2 主程序MyChessAndGoGame设计/实现方案辅之以执行过程的截图,介绍主程序的设计和实现方案,特别是如何将用户在命令行输入的指令映射到各ADT的具体方法的执行。

(1)主函数:
在这里插入图片描述
运行过程:
在这里插入图片描述
(2)以国际象棋为例
(3)根据不同选项进行不同操作的函数,查询和计算不会轮换对手
在这里插入图片描述
(4)程序结束,打印双方走棋历史
在这里插入图片描述

3.3.3 ADT和主程序的测试方案

1.ActionsInstanceTest

Test策略:
@Test(expected=AssertionError.class)make sure assertions are enabled with VM argument: -ea
public void test_CreatePlayer_GetPlayer()有重复玩家、无重复玩家
public void test_Detach()有无棋子、坐标在棋盘内、坐标不在棋盘内

2.BoardTest

Test策略:
public void test()检查棋盘大小是否相等、在棋盘上放置棋子,看能否得到正确的棋子

3.PieceTest

Test策略:
public void test()判断名字、颜色是否相等,该棋子和它的克隆不相等

4.PlayerTest

Test策略:
public void test()检查玩家名字,颜色是否相等,添加棋子重复和不重复,能否得到正确的走棋历史

5.PositionTest

Test策略:
public void test()能够得到正确的横纵坐标,检查toString
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值