GUI界面开发

开发运行环境

  运行环境:JDK1.8

  运行命令:java -jar sudokuGUI.jar

  语言:java

  开发环境:Intellij IDEA 2019.2,JavaFX Scene Builder 8.3.0

项目结构和说明

  为了利用之前的源代码,UI界面采用javafx进行开发,使用MVC框架来设计整个应用,使用了数据绑定,通过构建容器组件,添加menu、监听器等实现图形化界面功能。

软件功能说明

  主要页面如下所示,一打开应用自动进行计时。

java rxtx库下载 javafx ui库_数独

  点击菜单中的开始,可以开始新游戏、提交当前页面,查看答案,退出游戏。

java rxtx库下载 javafx ui库_UI_02

  点击提交时,计时器停止,若有空位置没有填,会提示填满再提交,若有错误会弹窗会提示,完全正确时会弹窗恭喜用户。

java rxtx库下载 javafx ui库_数独_03

java rxtx库下载 javafx ui库_UI_04

java rxtx库下载 javafx ui库_命令行_05

面向对象分析设计

用例图

java rxtx库下载 javafx ui库_UI_06

类图

总共有五个类
Main用于显示UI界面,界面用xml编写,在sample.xml中。
Controller监听图形页面、鼠标、键盘等。
Solve验证用户提交的数独是否正确。
Generate用于生成终局,对终局随机挖空,形成数独,显示在UI中。
AlterInfo用于弹窗提示。
SudokuCell表示数独中的每一个小块,控制是否可以输入,显示数字等。

java rxtx库下载 javafx ui库_java rxtx库下载_07

状态图

java rxtx库下载 javafx ui库_数独_08

设计思路

  GUI中的主体代码和命令行部分几乎一致,最开始选择生成数独的回溯算法。最初实现UI界面,用了优化以后利用排列组合快速生成终局的算法,但因为终局是由变换第一宫形成的,所以存在规律性,降低数独的可玩性。所以采用了最初生成终局的回溯算法。

  实现思路是先通过回溯算法生成一个终局,因为要求最少挖30个空,最多挖60个空,每个宫中最少有两个。当每个最少挖4个,4×9=36符合要求,每个宫最多挖6个,6×9=54个符合要求。所以循环九个宫,每个宫产生一个随机数n(4<=n<=6),然后在1-9中生成n个不同的随机数,在该宫中将n个随机数所在的位置挖掉,便生成了一个数独。

  在编写代码的过程中,卡壳了很久一直在思考如何保证数独解的唯一性,但因为自己对这部分算法的理解并不是很深入,所以放弃了保证了数独解的唯一性。用户提交数独时,不与最初生成的终局比较,而是利用循环检查用户提交的答案中是否有错误,没有错误即为正确答案。若用户选择查看答案,则提供最初的终局。

  自定义了一个数据类型SudokuCell,来存放数独中的每一个小块,其中设置一个属性write保证可以多次修改答案,若数独中该位置需要填写,则将write设置为true,若不需要则设置为false,并且可以对每一个SudokuCelle用css进行美化,使数独的外观更加美观。

具体代码实现

  对用户提交数独进行检查,正确时返回true,错误时返回false,这个方法在命令行中用于测试,检查对txt数独中求解时,是否有错误。

/**
	 * @Title: checkSolution
	 * @Description: 检查结果
	 * @param  data
	 * @return boolean
	 * @throws
	 */
	boolean checkSolution(int[] data)
	{
		int index=0;
		int[] criterion=new int[27];
		Solve s=new Solve();
		for (int j = 0; j < 27; j++) {
			criterion[j] = 511;
		}
		s.setCriterion(criterion);
		if(!checkSudoku(data,index,s))
			return false;
		return true;
	}
/**
 * @Title: checkSudoku
 * @Description: 检查数独答案是否正确
 * @param  data
 * @param  index
 * @param  s
 * @return boolean
 * @throws
 */
private boolean checkSudoku(int[] data,int index,Solve s) {
	for (int j = 0; j < 9; j++) {
		for (int k = 0; k < 9; k++) {
			while (data[index]>9 || data[index]<1)
			{
				index++;
			}
			int temp = data[index++];
			if (!s.fill(j, k, temp)) {
				Logger logger=Logger.getLogger("SolveTest");
				logger.setLevel(Level.SEVERE);
				String msg="row:"+(j+1)+"clo:"+(k+1)+"value:"+temp;
				logger.severe(msg);
				return false;
			}else{
				s.usedNum(j,k,temp);
			}
		}
	}
	return true;
}

测试

  因为GUI项目中,除了UI部分代码,都是在命令行中经过测试的代码,所以只进行简单的系统测试,检测页面的响应、监听等是否正常。

编号

操作

预期结果

实际结果

状态

1

页面有空位,点击提交

未完成弹窗

未完成弹窗

通过

2

页面没有空位,存在错误,点击提交

错误弹窗

错误弹窗

通过

3

正确完成数独,点击提交

正确弹窗

计时停止

正确弹窗

计时停止

通过

4

点击查看答案

显示答案

计时停止

显示答案

计时停止

通过

5

点击退出

退出程序

退出程序

通过

6

点击新游戏

开始新游戏

开始新游戏

通过

7

在空位输入非数字字符

输不进去

输不进去

通过

8

在空位输入数字字符

空位显示该数字

空位显示该数字

通过

9

点击查看答案以后,点击提交

正确弹窗

正确弹窗

通过

10

点击关于

信息弹窗

信息弹窗

通过

11

点击帮助

帮助弹窗

帮助弹窗

通过

简要开发过程

时间

内容

2019年12月19日 - 2019年12月20日

需求分析、概要设计

2019年12月26日 - 2020年1月1日

基本完成命令行功能

2019年12月26日 - 2020年1月1日

开始单元测试

2020年1月2日 - 2020年1月3日

修改算法、对代码结构进行优化,完成测试

2020年1月4日 - 2020年1月16日

代码质量检测、UI编写

2020年1月17日 - 2020年1月18日

博客优化