github地址:https://github.com/Duuang/Project-Sudoku
日期:2018-12-15
3. 设计阶段
设计分结构化设计方法,和面向对象的设计方法。结构化程序写太多了,这次打算试试面向对象的。而且结构化程序总感觉代码多了的话就贼长,整体结构容易弄不清楚。因为还没讲后面的面向对象设计,所以自己稍微看了些后面章节内容,结合第3章的软件设计基础,自己尝试做了下设计阶段:
一、概要设计
包括了:(1)体系结构设计 (2)界面设计 (3)数据设计
(1)体系结构设计
主要就是确定类、和类间关系。
根据模块化设计的思想,分成了三个类:
① ConsoleParameter类,代表控制台输入的参数,包含了参数处理的功能
② SudokuSolution类,数独解类(就是没有0的数独),能生成指定数量数独题,用于生成数独题
③ SudokuPuzzle类,数独题类(有0的数独),可以生成生成数独解。
// 这里我之前想错了。。写完前两个类了才觉得好像名字有点不对劲。。之前把②③名字弄反了,实际上生成数独应该是SudokuSolution类里的方法,因为相当于生成没有0的数独解(但是这个感觉和这个数独解类关系不太大。。只有一个函数)。。而第三个SudukuPuzzle类对应求解数独功能,是SudukuPuzzle.solve()才对。。
也想过要不要把SudokuSolution和SudokuPuzzle合并成一个类,就代表一个数独的意思,然后空着的地方用0表示。但是这两种还是有不同的,比如带0的可以解,不带0的没法解。要区分的话也可以加个成员变量区分,不过感觉还是分开好点,可能对以后可能的扩展有利些。。所以就分成了这3个类。
类间关系:
SudokuSolution和SudokuPuzzle类都能接受ConsoleParameter类,来获取控制台参数,并进行相应动作
(2)界面设计
没有用户界面(附加题做的时候再设计)
(3)数据设计
数据库、数据文件、全局数据结构的定义,好像用不上
二、详细设计
还是先做一个最初版本的详细设计吧,感觉之后可能在实现过程中还会更改这个详细设计
主要就是对类里面函数和变量的定义
ConsoleParamter类:
用来获取控制台参数,并处理,判断错误,得到两个参数,之后可以用于生成数独或求解数独时的参数
详细说明:(直接写在.h文件里了)
//
//用来获取控制台参数,并处理,判断错误,得到两个参数
//之后可以用于生成数独或求解数独时的参数
//
class ConsoleParameter {
public:
// 根据argc和argv,初始化所有成员变量
ConsoleParameter(int argc, char *argv[]);
// 获取-c或者-s指令,失败返回'\0'
char GetCommand();
// 获取-c或-s后面的参数,失败返回"\0"
string GetOperationcode();
private:
// 向控制台显示错误信息
void OutputError(string errorstring);
// argc,控制台参数个数
int argc;
// argv,多个控制台参数数组的首地址
char **argv;
//存放-c或者-s,或者空
char command;
//存放-c或者-s后面的参数
string operationcode;
};
其中,ExtractCommand()函数流程图:
ExtractOperationCode()函数流程图
SudokuSolution类:
接收ConsoleParameter对象,并生成数独,输出到文件
详细说明:
//
//接收ConsoleParameter对象,并生成数独,输出到文件
//
class SudokuSolution {
public:
//用ConsoleParameter类的parameter来初始化对象
SudokuSolution(ConsoleParameter parameter);
//生成parameter参数中数量的对象,并存至文件
void Generate();
private:
//生成25个基础数独(不能通过1到9的排列使之相同的,算不同的数独)
//被Generate()调用
void GenerateBasicPuzzle();
//用于初始化对象
ConsoleParameter parameter;
//存放25个基础数独,下标从0开始
int basic_puzzle[25][10][10];
};
Generate()函数流程图:
SudokuPuzzle类:
接收ConsoleParameter对象,并求解文件中数独,输出到sudoku_answers文件
详细说明:
//
//接收ConsoleParameter对象,并求解文件中数独,输出到sudoku_answers文件
//
class SudokuPuzzle {
public:
//用ConsoleParameter类的参数初始化对象(无默认构造函数),并初始化所有数据成员
SudokuPuzzle(ConsoleParameter parameter);
//用于关闭两个文件
~SudokuPuzzle();
//调用dfs_solve(),解文件中的所有数独题,并输出到sudoku_answers文件
int SolveAll();
private:
//用于根据puzzle[10][10]解一个数独,把解存至solution[90]
void dfs_solve(int depth);
//用于构造对象
ConsoleParameter parameter;
//存数独题,0代表空格,1~9行和1~9列为有效数据
int puzzle[10][10];
//数独题是否符合格式要求
bool islegal;
//数独题中的0个数
int number_of_blanks;
//数独题中每个0的位置,从0下标开始
int position_of_blanks[90][2];
//存数独的解,从0下标开始
int solution[90];
//数独是否有解
bool solvable;
//输入文件的指针
FILE *finput;
//输出文件的指针
FILE *foutput;
//表示读了几个题进来,纯粹是为了输出到文件的时候区分第一个
int count;
};
SolveAll()流程图: