软件构造 Lab-2 Report

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 实验环境配置

在github上git clone老师的仓库,然后再在eclipse中选择import a existed project。
私有仓库地址

3 实验过程

请仔细对照实验手册,针对三个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。

3.1 Poetic Walks

构造一个泛型接口Graph,可以采用两种不同的方式实现,分别是点图和边图。在problem4当中,根据已经构造的graph,生成一个有关语言的图,并根据这个图自动补齐输入词组。

3.1.1 Get the code and prepare Git repository

git init
git remote add origin https://github.com/ComputerScienceHIT/Lab2-1180300410.git
git clone

3.1.2 Problem 1: Test Graph

现在Graph当中采用一种方法构造一个emptyGraph,这里采用ConcreteEdgesGraph。

public static <L> Graph<L> empty() {
		Graph<L> graph = new ConcreteEdgesGraph<L>();
		return graph;
	}

3.1.3 Problem 2: Implement Graph

3.1.3.1 Implement ConcreteEdgesGraph

采用一个Set集合和List<Edge>列表分别保存图的顶点和边。
// Abstraction function:
// represent a set of edges from a source
// Representation invariant:
// the weight is nonnegative
// edges are less than n * (n + 1)
// only an edge between the a source and a target
其中有add,remove,set,sources,targets等操作。除此之外,还有另外一个Edge类来保存边,域中有source边,target边和权值。

3.1.3.2 Implement ConcreteVerticesGraph

采用一个List<Vertex>保存图。
// Abstraction function:
// vertices represent the node in a graph
// two maps in Vertex represent the in and out edge to a vertex
// Representation invariant:
// Vertex may not be null
// elements in in map is similar to out map
// weight -> nonnegative
// Safety from rep exposure:
// use private and final to protect
与3.1.3.1有相同的操作。其中还有另外一个Vertex类来保存一个点,以及与这个点相邻的点的信息,用一个Map<L, Integer>分别保存相邻的顶点和边的权值。

3.1.4 Problem 3: Implement generic Graph

3.1.4.1 Make the implementations generic

将上面完成的两个文件中所有用到String的地方改成即可实现泛型。

3.1.4.2 Implement Graph.empty()

采用ConcreteEdgesGraph实现,构造一个空的ConcreteEdgesGraph。

3.1.5 Problem 4: Poetic walks

3.1.5.1 Test GraphPoet

// Testing strategy
// Partition of input:empty String, one word, some words

3.1.5.2 Implement GraphPoet

根据读入的文件构造一个图,再根据这个图对输入进行补全。

		for (int i = 0; i < (words.length - 1); i++) {
			sources = graph.sources(words[i + 1].toLowerCase());
			targets = graph.targets(words[i].toLowerCase());
			sb.append(words[i].toLowerCase() + " ");
			int weight = 0;
			String bridge = "";
			for (String word : targets.keySet()) {
				if (sources.keySet().contains(word)) {
					if (sources.get(word)+ targets.get(word) > weight) {
						weight = sources.get(word) + targets.get(word);
						// sb.append(word + " ");
						bridge = word;
					}
				}
			}
			if (weight > 0) {
				sb.append(bridge.toLowerCase() + " ");
			}
		}
		sb.append(words[words.length - 1].toLowerCase());
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仓库。
在这里给出你的项目的目录结构树状示意图。
在eclipse中按照图形化的界面提交。commit and push。
项目名称: Lab2-1180300410
src
  P0
   graph
    ….java
   poet
    ….java
    ….txt
test
  P1
   graph
    …Test.java
   poet
    …Test.java
    ….txt

3.2 Re-implement the Social Network in Lab1

基于3.1完成的图实现Lab1中的FriendshipGraph。

3.2.1 FriendshipGraph类

	private Graph<Person> graph = Graph.empty();

	public void addVertex(Person person) {
		graph.add(person);
	}
	
	public void addEdge(Person person1, Person person2) {
		graph.set(person1, person2, 1);
	}

getDistance依然采用DFS实现。

3.2.2 Person类

此处直接将Lab1的Person类copy过来就可。

3.2.3 客户端main()

采用与Lab1相同的客户端main。

	public static void main(String[] args) {
		FriendshipGraph graph = new FriendshipGraph();
		Person rachel = new Person("Rachel");
		Person ross = new Person("Ross");
		Person ben = new Person("Ben");
		Person kramer = new Person("Kramer");
		//Person k = new Person("Ben");
		//graph.addVertex(k);
		graph.addVertex(rachel);
		graph.addVertex(ross);
		graph.addVertex(ben);
		graph.addVertex(kramer);
		graph.addEdge(rachel, ross);
		graph.addEdge(ross, rachel);
		graph.addEdge(ben, ross);
		graph.addEdge(ross, ben);
		System.out.println(graph.getDistance(rachel, ross));
		System.out.println(graph.getDistance(rachel, ben));
		System.out.println(graph.getDistance(rachel, rachel));
		System.out.println(graph.getDistance(rachel, kramer));
	}

3.2.4 测试用例

仍然采用与Lab1相同的测试用例。
在这里插入图片描述

3.2.5 提交至Git仓库

如何通过Git提交当前版本到GitHub上你的Lab3仓库。
在这里给出你的项目的目录结构树状示意图。
在eclipse中按照图形化的界面提交。commit and push。
项目名称: Lab2-1180300410
src
  P2
   FriendshipGraph.java
   Person.java
test
  P2
   FriendshipGraphTest.java

3.3 Playing Chess

3.3.1 ADT设计/实现方案

3.3.1.1 Position类

//fields
private int x;
private int y;
// Abstraction function:
// x is the x line in the UCS
// y is the y line in the UCS
// (0, 0) is the left and down corner
// Representation invariant:
// both are nonnegative
// Safety from rep exposure:
// use private

3.3.1.2 Player类

//fields
private final String name;
private final Type color;
private List pieceList = new ArrayList<>();
// Abstraction function:
// the name of player represent a player
// player1 use WHITE while player2 use BLACK
// the pieces the player has are in the pieceList
// Representation invariant:
// the name may not be similar
// all the fields may not be null
// Safety from rep exposure:
// use private and final and defined copy

3.3.1.3 Action类

the search and calculate piece number method in a game. no constructor, AF, RI and so on.

3.3.1.4 Type类
  • the type and color of pieces.
  • BLACK and WHITE in go game.
  • the others in chess game.
  • besides BLACK and WHITE also represent the color.
3.3.1.5 Piece类

//fields
private final Type type;
private final Player player;
// Abstraction function:
// the type is the kind of the piece
// player is the owner of the piece
// Representation invariant:
// type and player are not null
// Safety from rep exposure:
// use private and final

3.3.1.6 Board类

//fields
private int size;
private final Map<Position, Piece> board = new HashMap<>();
// Abstraction function:
// size is the size of the board
// the map’s key is a position on the board
// the map’s value is the piece on the position
// Representation invariant:
// size is nonnegative. in fact, it’s 8 or 19
// the map is not null
// Safety from rep exposure:
// use private, final, and defined copy

3.3.1.7 Game类

//fields
private Board gameBoard;
private final Player player1;
private final Player player2;
private final Action action = new Action();
private final StringBuilder sb = new StringBuilder("");
// Abstraction function:
// use gameBoard to represent a board in a game
// two players are player1 and player2
// sb to record the operation
// Representation invariant:
// gameBoard, player1, and player2 is not null
// Safety from rep exposure:
// use private and final

3.3.2 主程序MyChessAndGoGame设计/实现方案

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

初始化部分:

	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		Game game;
		while (true) {
			System.out.println("请输入游戏(chess or go): ");
			String s = input.next();

围棋部分:

			if (s.equals("go")) {
				System.out.println("请输入玩家1的名字: ");
				String player1 = input.next();
				String player2;
				while(true)
				{
					System.out.println("请输入玩家2的名字: ");
					player2 = input.next();
					if(! player2.equals(player1))
						break;
					System.out.println("不允许重名,请重新输入");
				}
				game = new Game(player1, player2);
				game.init(false);
				int i = 1;
				while (s != "end") {
					i = i % 2;
					System.out.println("现在是" + game.getPlayer(i).getName() + "操作: ");
					System.out.println("1. 落子");
					System.out.println("2. 提子");
					System.out.println("3. 打印棋盘");
					System.out.println("4. 查询位置");
					System.out.println("5. 计算我的棋子数目");
					System.out.println("6. 计算对方棋子数目");
					System.out.println("7. 跳过");
					System.out.println("end. 结束");
					s = input.next();
					if(s.equals("end"))
						break;
					int choose = Integer.valueOf(s);
					switch(choose) {
						case 1:
							System.out.println("请输入落子位置: ");
							game.put(new Position(input.nextInt(), input.nextInt()), new Piece(i == 1 ? Type.WHITE : Type.BLACK, game.getPlayer(i)));
							i = i + 1;
							break;
						case 2:
							System.out.println("请输入要移除棋子的位置: ");
							game.remove(game.getPlayer(i), new Position(input.nextInt(), input.nextInt()));
							i = i + 1;
							break;
						case 3:
							game.print();
							break;
						case 4:
							System.out.println("请输入要查询的位置: ");
							Position p = new Position(input.nextInt(), input.nextInt());
							System.out.println(game.search(p) == null ? "此处无棋子" : game.search(p).pieceImformation());
							break;
						case 5:
							System.out.println(game.getPlayer(i).getName() + "的棋子数量是" + game.calculatePieceNumber(game.getPlayer(i)));
							break;
						case 6:
							System.out.println(game.getPlayer(i + 1).getName() + "的棋子数量是" + game.calculatePieceNumber(game.getPlayer(i + 1)));
							break;
						case 7:
							game.skipe(game.getPlayer(i));
							i = i + 1;
							break;
						default:
							System.out.println("请重新输入");
							continue;
					}
						
				}
				game.history();
				break;
}

国际象棋部分:

else if (s.contentEquals("chess")) {
				System.out.println("请输入玩家1的名字: ");
				String player1 = input.next();
				String player2;
				while(true)
				{
					System.out.println("请输入玩家2的名字: ");
					player2 = input.next();
					if(! player2.equals(player1))
						break;
					System.out.println("不允许重名,请重新输入");
				}
				game = new Game(player1, player2);
				game.init(true);
				int i = 1;
				while (s != "end") {
					i = i % 2;
					System.out.println("现在是" + game.getPlayer(i).getName() + "操作: ");
					System.out.println("1. 移子");
					System.out.println("2. 吃子");
					System.out.println("3. 打印棋盘");
					System.out.println("4. 查询位置");
					System.out.println("5. 计算我的棋子数目");
					System.out.println("6. 计算对方棋子数目");
					System.out.println("7. 跳过");
					System.out.println("end. 结束");
					s = input.next();
					if(s.equals("end"))
						break;
					int choose = Integer.valueOf(s);
					switch(choose) {
						case 1:
							System.out.println("请输入要移动棋子的位置: ");
							Position source = new Position(input.nextInt(), input.nextInt());
							System.out.println("请输入要移动到的位置: ");
							Position target = new Position(input.nextInt(), input.nextInt());
							game.move(game.getPlayer(i), source, target);
							i = i + 1;
							break;
						case 2:
							System.out.println("请输入要移动棋子的位置: ");
							Position source1 = new Position(input.nextInt(), input.nextInt());
							System.out.println("请输入要吃棋子的位置: ");
							Position target1 = new Position(input.nextInt(), input.nextInt());
							game.eat(game.getPlayer(i), source1, target1);
							i = i + 1;
							break;
						case 3:
							game.print();
							break;
						case 4:
							System.out.println("请输入要查询的位置: ");
							Position p = new Position(input.nextInt(), input.nextInt());
							System.out.println(game.search(p) == null ? "此处无棋子" : game.search(p).pieceImformation());
							break;
						case 5:
							System.out.println(game.getPlayer(i).getName() + "的棋子数量是" + game.calculatePieceNumber(game.getPlayer(i)));
							break;
						case 6:
							System.out.println(game.getPlayer(i + 1).getName() + "的棋子数量是" + game.calculatePieceNumber(game.getPlayer(i + 1)));
							break;
						case 7:
							game.skipe(game.getPlayer(i));
							i = i + 1;
							break;
						default:
							System.out.println("请重新输入");
							continue;
					}
				}
				game.history();
				break;
			} else {
				System.out.println("请重新输入 ");
			}
		}

3.3.3 ADT和主程序的测试方案

3.3.3.1 ActionTest

// Testing strategy:
// when the result is null, or not null
// when the result is zero, or negative

3.3.3.2 BoradTest

//Testing strategy:
// the board is empty or not empty

3.3.3.3 PieceTest

//Testing strategy:
// divided into piece with the same or different name

3.3.3.4 PlayerTest

//Testing strategy:
// the player have no piece or some pieces

3.3.3.5 PositionTest

//Testing strategy:
// divided into:
// 1. X is different and Y is different
// 2. only X   3. only Y
// 4. both are different

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值