java数独流程图_软件工程个人项目总结-数独
Github項(xiàng)目地址
包含博客
這篇博客將之前的每周所發(fā)整合成了一篇
PSP表格
PSP2.1
Personal Software Process Stages
預(yù)估耗時(shí)(分鐘)
實(shí)際耗時(shí)(分鐘)
Planning
計(jì)劃
60
60
· Estimate
· 估計(jì)這個(gè)任務(wù)需要多少時(shí)間
60
60
Development
開發(fā)
870
1710
· Analysis
· 需求分析 (包括學(xué)習(xí)新技術(shù))
120
120
· Design Spec
· 生成設(shè)計(jì)文檔
120
160
· Design Review
· 設(shè)計(jì)復(fù)審 (和同事審核設(shè)計(jì)文檔)
60
30
· Coding Standard
· 代碼規(guī)范 (為目前的開發(fā)制定合適的規(guī)范)
120
60
· Design
· 具體設(shè)計(jì)
60
120
· Coding
· 具體編碼
240
500
· Code Review
· 代碼復(fù)審
30
120
· Test
· 測試(自我測試,修改代碼,提交修改)
120
600
Reporting
報(bào)告
150
240
· Test Report
· 測試報(bào)告
60
120
· Size Measurement
· 計(jì)算工作量
30
30
· Postmortem & Process Improvement Plan
· 事后總結(jié), 并提出過程改進(jìn)計(jì)劃
60
90
合計(jì)
1080
2010
需求分析
需求
運(yùn)行一個(gè)命令行程序,程序能:
1. 生成不重復(fù)的數(shù)獨(dú)終局至文件。
2. 讀取文件內(nèi)的數(shù)獨(dú)問題,求解并將結(jié)果輸出到文件。
數(shù)據(jù)建模
將數(shù)獨(dú)分成9個(gè)宮進(jìn)行求解,ER表示如下,因?yàn)閿?shù)獨(dú)左上角第一塊確定,所以將其看作數(shù)獨(dú)的屬性。
功能建模
數(shù)據(jù)源:用戶
數(shù)據(jù)終點(diǎn):文件
主要數(shù)據(jù)流:生成指令、求解指令、數(shù)獨(dú)(待求解),以及終局
主要支持文件:待求解數(shù)獨(dú)文件
主要處理過程:生成終局、求解數(shù)獨(dú)
0層圖
對(duì)系統(tǒng)進(jìn)行求精,劃分系統(tǒng)的子系統(tǒng)。
行為建模
解題思路
在最開始拿到題目的時(shí)候,想起上學(xué)期算法課程學(xué)過的回溯算法,決定用會(huì)回溯算法進(jìn)行實(shí)現(xiàn),所以翻看了算法設(shè)計(jì)的課本和ppt,對(duì)回溯算法重新進(jìn)行了學(xué)習(xí)。在生成n個(gè)不同局面和求解給定數(shù)獨(dú)的思路大致一致,但有在細(xì)節(jié)處的處理有些不同。首先是生成n個(gè)不同的局面,按行進(jìn)行循環(huán),有一個(gè)二維數(shù)組保存每個(gè)位置的可能數(shù)字,從可能數(shù)字中隨機(jī)選一個(gè)放在該位置,若該位置找不到可能的位置,則回到上一個(gè),修改上一個(gè)位置的解。不斷進(jìn)行回溯,直到所有的位置都合法。若是對(duì)給定局面進(jìn)行求解,則將空白位置用數(shù)組記錄下來,只對(duì)空白位置進(jìn)行回溯即可。
但在該回溯算法中,搜索時(shí)盲目的,效率較低,最差的實(shí)現(xiàn)對(duì)每個(gè)空方格試探所有可能的數(shù)字,有大量的時(shí)間浪費(fèi)。并且如果需要生成多個(gè)終局時(shí),每一個(gè)終局都是通過回溯實(shí)現(xiàn),且生成不同的終局由Random()進(jìn)行數(shù)字選擇實(shí)現(xiàn),但實(shí)際上Random生成偽隨機(jī)數(shù),在一定時(shí)間會(huì)生成相同隨機(jī)數(shù),無法保證在生成終局?jǐn)?shù)目足夠大時(shí),不會(huì)產(chǎn)生兩個(gè)相同的終局。
因?yàn)樗惴ㄐ视泻艽蟮母倪M(jìn)空間,以及無法保證在n足夠大時(shí),所有終局都相異,所以在對(duì)代碼重構(gòu)的過程中,引入了排列組合的算法,對(duì)原有進(jìn)行優(yōu)化。將數(shù)獨(dú)分成9個(gè)3X3的小方塊,每個(gè)小方塊是一個(gè)宮。
參考維基百科提供的一個(gè)生成終局思路,由第一宮生成其余八個(gè)宮。對(duì)第一宮中的塊進(jìn)行排列組合即可,因?yàn)樯山K局時(shí),要求左上角的第一個(gè)數(shù)為:(學(xué)號(hào)后兩位相加)%9+1,(1+3)%9+1=5,所以左上角為5,且不允許改變。即在第一宮內(nèi)只有八個(gè)塊可以移動(dòng),有8!=40320種情況,并且在每一宮內(nèi)(除了第一宮)進(jìn)行列列變換有3!×3!×3!×3!=1296,第二宮和第三宮可以交換,第四宮和第七宮可以交換有2!×2!=4,總共可以生成209,018,880個(gè)終局(大于1,000,000),此方案可行。
對(duì)于各種全排列,使用遞歸的方式實(shí)現(xiàn)。
設(shè)計(jì)實(shí)現(xiàn)過程
???編譯器:Intellij IDEA 2019.2
???語言:java
???運(yùn)行環(huán)境:JDK 1.8
活動(dòng)圖
順序圖
下面是生成終局的順序圖
下面是求解數(shù)獨(dú)的順序圖
類圖
???共有三個(gè)類,Main用于判斷輸入是否合法、將終局寫入文件、判斷輸入命令是否合法,Generate類用于生成終局,Solve類用于求解數(shù)獨(dú)。
具體代碼說明
Generate中主要函數(shù):
?generateSudoku 外部調(diào)用的接口,傳入一個(gè)n(n<=1,000,000),即可以生成n個(gè)終局。
createSeed 將第一宮作為種子,進(jìn)行交換操作,得到不同的種子。
createMap 通過種子的變換,得到該種子生成的第一個(gè)終局。
changeIndex 對(duì)于第一個(gè)終局進(jìn)行行列變換,生成不同的終局。
writeToOutput 將生成的int[ ] [ ]的終局,按照輸出格式要求,存放在一個(gè)char[]中 。
changeIndex流程圖如下
具體實(shí)現(xiàn)代碼如下所示,在goalNum=1時(shí),不用進(jìn)行變換,在>1開始,先交換index[16]和index[17],即先在第三大列內(nèi)進(jìn)行列變換,可以有6中不同的終局,接著在第二大列內(nèi)進(jìn)行交換,依次類推,到行進(jìn)行交換,可以快速產(chǎn)生大量不相同的終局。
/**
* @Title: changeIndex
* @Description: 對(duì)宮內(nèi)的行列進(jìn)行全排列
* @param a
* @param start
* @param end
* @return void
* @throws
*/
public void changeIndex( int start, int end) {
int i;
//分段進(jìn)行全排列
if (start == end) {
if (end == 5) {
changeIndex( 6, 8);
}else if(end==8){
changeIndex( 12, 14);
}else if(end==14){
changeIndex( 15, 17);
}
else {
writeToOutput();
}
}
else {
for (i = start; i <= end; i++) {
swap(index, start, i);
changeIndex( start + 1, end);
if (nowNum == goalNum) break;
swap(index, start, i);
}
}
}
Solve中主要函數(shù)
findSolution外部調(diào)用的接口,傳入一個(gè)txt的絕對(duì)路徑,即可對(duì)該txt中的數(shù)獨(dú)進(jìn)行求解。
dealFile將txt中的所有數(shù)獨(dú),存在一個(gè)int[]中,并得到要求解的數(shù)獨(dú)數(shù)目。
initCriterion將Criterion(表示行列宮沒有用過的數(shù))初始化,并將數(shù)獨(dú)中出現(xiàn)過的數(shù)在Criterion進(jìn)行標(biāo)記。
chooseCriterion遞歸對(duì)數(shù)獨(dú)進(jìn)行求解。
chooseCriterion流程圖
chooseCriteron和dealWithCriterion是求解數(shù)獨(dú)的主要兩個(gè)函數(shù)。chooseCriterion中state表示當(dāng)前是否能找到可行解,找到返回true,沒找返回false。先循環(huán)1-9九個(gè)數(shù),找到一個(gè)所在行、列、宮都沒有使用過的數(shù)放入,然后調(diào)用dealWithCriterion函數(shù),若后面的位置沒有待求解位置,則返回true,此時(shí)state為true,結(jié)束求解。若后面仍有待求解位置(a,b),則dealWithCriterion函數(shù)返回chooseCriterion(a, b)進(jìn)行求解,若可以找到可行解,則前面所求解保留,若找不到,則修改前面找到的可行解。本質(zhì)是利用回溯算法進(jìn)行求解。
起初兩個(gè)函數(shù)寫在一起,但在代碼質(zhì)量檢查時(shí),該函數(shù)復(fù)雜度太高,所以拆分成兩個(gè)函數(shù)
/**
* @Title: chooseCriterion
* @Description: 回溯選擇合適的數(shù)
* @param row
* @param col
* @return boolean
* @throws
*/
private boolean chooseCriterion(int row, int col) {
int value;
boolean state = false;
for (int k = 0; k < 9; k++) {
if(!state) {
value = k + 1;
if (!fill(row, col, value)) {
continue;
}
map[row][col] = value;
usedNum(row, col, value);
state = dealWithCriterion(row, col);
if (!state) {
releaseNum(row, col, value);
map[row][col] = 0;
}
}
}
return state;
}
/**
* @Title: dealWithCriterion
* @Description: 查找是否有空位要求解
* @param row
* @param col
* @return boolean
* @throws
*/
public boolean dealWithCriterion( int row, int col) {
//沒有空位
boolean state = false;
for (; row < 9; row++) {
for (; col < 9; col++) {
if (map[row][col] == 0) {
state = true;
break;
}
}
if (state)
break;
col = 0;
}
//沒有空位
if (!state) {
return true;
}
return chooseCriterion(row, col);
}
Main中主要函數(shù)
stringToFile傳入一個(gè)char[],將其寫入可執(zhí)行文件同級(jí)文件夾中的layout.txt(沒有會(huì)創(chuàng)建)。
isNumeric,whetherSolve,whetherGenerate都是判斷輸入是否合法。
測試
?使用Junit5對(duì)三個(gè)類分別進(jìn)行單元測試,單元測試的編寫思路是黑盒測試,運(yùn)用了路徑覆蓋和邊界覆蓋。對(duì)接口功能、邊界條件等進(jìn)行測試,并使測試覆蓋率盡可能,測試用例盡可能全面。
?MainTest用于測試輸入是否合法,以及是否可以順利寫入文件,
?GenerateTest測試其中的函數(shù)是否正常,并進(jìn)行了重復(fù)性檢測,檢測器生成的1000個(gè)終局中是否有相同的情況。
?SolveTest對(duì)Solve中部分主要函數(shù)進(jìn)行了檢測,并對(duì)求解結(jié)果進(jìn)行了有效性檢測,判斷是否是否求出了正確的數(shù)獨(dú)解。
?單元測試覆蓋率
Main部分測試設(shè)計(jì)(期待狀態(tài)=實(shí)際狀態(tài),即為成功)
編號(hào)
內(nèi)容
狀態(tài)
1
args[0]=11,args[1]=null
成功
2
args[0]="-c", args[1]="0"
成功
3
args[0]="-c", args[1]="1_000_001"
成功
4
args[0]="-c", args[1]="1_000_000"
成功
5
args[0]="-c", args[1]="D:/1.txt"
成功
6
args[0]="-s", args[1]="D:/1.txt"
成功
7
args[0]="-s", args[1]="D:/app/"
成功
Generate部分測試用例
函數(shù)
內(nèi)容
狀態(tài)
createSeed
seed={1,2,...9},goalNum=1
成功
createSeed
seed={1,2,...9},goalNum=100
成功
createMap
int[][] temp={{5,1,2,7,8....},goal=1
成功
createMap
int[][] temp={{5,1,2,7,8....},goal=1
成功
swap
交換兩個(gè)數(shù)
成功
generateSudoku
count=1000(檢測生成的1000個(gè)終局是否重復(fù))
成功
generateSudoku
count=1,000,000(檢測生成的1,000,000個(gè)終局是否重復(fù))
成功
Solve部分測試用例
函數(shù)
內(nèi)容
狀態(tài)
findSolution
PATH=txt路徑,里面有1000個(gè)數(shù)獨(dú),檢查找到的解是否正確
成功
findSolution
PATH=txt路徑,里面有100個(gè)高難數(shù)獨(dú),檢查找到的解是否正確
成功
fill
Criterion[0]=510,Criterion[9]=510,Criterion[18]=510,row=0,col=0,value=5;
成功
releaseNum
PATH=txt路徑,row=0,col=0,value=4;
成功
getBlock
row=0,col=0
成功
getBlock
row=3,col=4
成功
通過命令行執(zhí)行程序,對(duì)得到結(jié)果進(jìn)程測試
編號(hào)
命令行參數(shù)
結(jié)果
1
-c 0
能生成的終局在1-1,000,000之間
2
-c -1
能生成的終局在1-1,000,000之間
3
-c 1000
運(yùn)行成功
4
-c 1000000
運(yùn)行成功
5
-c 1000001
能生成的終局在1-1,000,000之間
6
-c
生成終局命令為:java sudoku -c 阿拉伯?dāng)?shù)字
7
-a
您的輸入不正確
生成終局命令為:java sudoku -c 阿拉伯?dāng)?shù)字
求解數(shù)獨(dú)命令為:java sudoku -s puzzle.txt的絕對(duì)路徑
8
-s D:\app\
路徑需指向一個(gè)txt文件
9
-s D:\app\unexisted.txt
系統(tǒng)找不到指定的文件
10
-s puzzle.txt
運(yùn)行成功
代碼質(zhì)量分析
?用SonarLint插件對(duì)每個(gè)java文件進(jìn)行代碼質(zhì)量優(yōu)化
?分析過后,除了Main類中因?yàn)樾枰蛴∶铄e(cuò)誤提示,仍存在一些warning,其余文件中的warning全部消除。
性能改進(jìn)
用Intellij中插件JProfiler進(jìn)行程序性能分析
最初的程序每生成一個(gè)終局,直接寫入文件,且進(jìn)行回溯時(shí),多次進(jìn)行值的交換。為了保證隨機(jī)性,每一次將所有可能值先放入鏈表,然后將隨機(jī)選取一個(gè)放入該空位。在求解數(shù)獨(dú)時(shí),先讀取一個(gè)數(shù)獨(dú),求解后寫入文件,再繼續(xù)讀取下一個(gè)數(shù)據(jù)。這種算法會(huì)頻繁創(chuàng)建很多對(duì)象,且讀寫會(huì)花費(fèi)大量的時(shí)間。
改進(jìn)后,時(shí)間上有了非常大的提升,且在回溯,用一個(gè)27位數(shù)組Criterion,前九位表示每一行可能解,中間九位表示每一列可能解,最后九位表示每一個(gè)宮的可能解,且每一個(gè)數(shù)可以表示成一個(gè)九位的二進(jìn)制,從右到左依次表示1-9,若Criterion[0]=000_000_001,則表示第一行只有1沒有用過,該位置的可行解只有1。選擇一個(gè)數(shù)時(shí)只需將該數(shù)與對(duì)應(yīng)的下標(biāo)的Criterion進(jìn)行與運(yùn)算,即可將該數(shù)標(biāo)記為使用,這樣減少了反復(fù)復(fù)制的時(shí)間。且改進(jìn)后不再隨機(jī)選取可行解,按順序進(jìn)行選擇。
并且改進(jìn)后每生成一個(gè)終局,先放在一個(gè)char數(shù)組中,生成所有的終局,統(tǒng)一寫入文件;在求解數(shù)獨(dú)時(shí),一次讀取出所有的待求解數(shù)獨(dú),每個(gè)分別求解,再統(tǒng)一寫入。
下圖為Jprofiler中提供的CallTree,通過樹形圖體現(xiàn)了方法間的層次調(diào)用關(guān)系,并按照?qǐng)?zhí)行總時(shí)間從小到大排列。
改進(jìn)之前,用FileWriter寫入文件,生成1000個(gè)終局需要12s左右。每生成一個(gè)終局馬上寫入文件。下圖看到關(guān)閉流花費(fèi)了大量的時(shí)間。
改進(jìn)后,用BufferedWrite寫入文件,由于含有緩沖區(qū),所以效率要比FileWriter高,但內(nèi)部仍用FileWrite進(jìn)行讀寫。在生成1000個(gè)終局時(shí),總耗時(shí)為0.034s。由下表寫入文件所消耗的時(shí)間遠(yuǎn)大于生成終局。
以后討論情況均為改進(jìn)以后
在生成1,000,000個(gè)終局時(shí),總耗時(shí)0.805。stringToFile,即將終局寫入文件所占比例最大,即耗時(shí)最長,但生成終局的方法generateSudoku執(zhí)行耗時(shí)雖然不是最長,但仍占有較大的比例。
綜合生成1000和1,000,000個(gè)終局可得,在生成終局的情況下,stringToFile時(shí)消耗最多的函數(shù)。
在求解數(shù)獨(dú)時(shí),首先讀取1000個(gè)數(shù)獨(dú),進(jìn)行求解,總耗時(shí)0.325s。此時(shí)findSolution函數(shù)耗時(shí)最多,但在這個(gè)函數(shù)中會(huì)調(diào)用其他函數(shù),其中dealFile即讀取文件耗時(shí)最多。
求解10,000個(gè)數(shù)獨(dú)時(shí),findSolution耗時(shí)最多,在該函數(shù)調(diào)用的函數(shù)中,SolveSudoku求解數(shù)獨(dú)的函數(shù)耗時(shí)超過了讀取文件的耗時(shí)。在求解數(shù)目較小,讀取文件的時(shí)間相對(duì)較長,在求解數(shù)獨(dú)變大以后,求解數(shù)獨(dú)的時(shí)間要更長。
GUI界面開發(fā)
開發(fā)運(yùn)行環(huán)境
運(yùn)行環(huán)境:JDK1.8
運(yùn)行命令:java -jar sudokuGUI.jar
語言:java
開發(fā)環(huán)境:Intellij IDEA 2019.2,JavaFX Scene Builder 8.3.0
項(xiàng)目結(jié)構(gòu)和說明
為了利用之前的源代碼,UI界面采用javafx進(jìn)行開發(fā),使用MVC框架來設(shè)計(jì)整個(gè)應(yīng)用,使用了數(shù)據(jù)綁定,通過構(gòu)建容器組件,添加menu、監(jiān)聽器等實(shí)現(xiàn)圖形化界面功能。
軟件功能說明
主要頁面如下所示,一打開應(yīng)用自動(dòng)進(jìn)行計(jì)時(shí)。
點(diǎn)擊菜單中的開始,可以開始新游戲、提交當(dāng)前頁面,查看答案,退出游戲。
點(diǎn)擊提交時(shí),計(jì)時(shí)器停止,若有空位置沒有填,會(huì)提示填滿再提交,若有錯(cuò)誤會(huì)彈窗會(huì)提示,完全正確時(shí)會(huì)彈窗恭喜用戶。
面向?qū)ο蠓治鲈O(shè)計(jì)
用例圖
類圖
總共有五個(gè)類
Main用于顯示UI界面,界面用xml編寫,在sample.xml中。
Controller監(jiān)聽圖形頁面、鼠標(biāo)、鍵盤等。
Solve驗(yàn)證用戶提交的數(shù)獨(dú)是否正確。
Generate用于生成終局,對(duì)終局隨機(jī)挖空,形成數(shù)獨(dú),顯示在UI中。
AlterInfo用于彈窗提示。
SudokuCell表示數(shù)獨(dú)中的每一個(gè)小塊,控制是否可以輸入,顯示數(shù)字等。
狀態(tài)圖
設(shè)計(jì)思路
GUI中的主體代碼和命令行部分幾乎一致,最開始選擇生成數(shù)獨(dú)的回溯算法。最初實(shí)現(xiàn)UI界面,用了優(yōu)化以后利用排列組合快速生成終局的算法,但因?yàn)榻K局是由變換第一宮形成的,所以存在規(guī)律性,降低數(shù)獨(dú)的可玩性。所以采用了最初生成終局的回溯算法。
實(shí)現(xiàn)思路是先通過回溯算法生成一個(gè)終局,因?yàn)橐笞钌偻?0個(gè)空,最多挖60個(gè)空,每個(gè)宮中最少有兩個(gè)。當(dāng)每個(gè)最少挖4個(gè),4×9=36符合要求,每個(gè)宮最多挖6個(gè),6×9=54個(gè)符合要求。所以循環(huán)九個(gè)宮,每個(gè)宮產(chǎn)生一個(gè)隨機(jī)數(shù)n(4<=n<=6),然后在1-9中生成n個(gè)不同的隨機(jī)數(shù),在該宮中將n個(gè)隨機(jī)數(shù)所在的位置挖掉,便生成了一個(gè)數(shù)獨(dú)。
在編寫代碼的過程中,卡殼了很久一直在思考如何保證數(shù)獨(dú)解的唯一性,但因?yàn)樽约簩?duì)這部分算法的理解并不是很深入,所以放棄了保證了數(shù)獨(dú)解的唯一性。用戶提交數(shù)獨(dú)時(shí),不與最初生成的終局比較,而是利用循環(huán)檢查用戶提交的答案中是否有錯(cuò)誤,沒有錯(cuò)誤即為正確答案。若用戶選擇查看答案,則提供最初的終局。
自定義了一個(gè)數(shù)據(jù)類型SudokuCell,來存放數(shù)獨(dú)中的每一個(gè)小塊,其中設(shè)置一個(gè)屬性write保證可以多次修改答案,若數(shù)獨(dú)中該位置需要填寫,則將write設(shè)置為true,若不需要?jiǎng)t設(shè)置為false,并且可以對(duì)每一個(gè)SudokuCelle用css進(jìn)行美化,使數(shù)獨(dú)的外觀更加美觀。
具體代碼實(shí)現(xiàn)
對(duì)用戶提交數(shù)獨(dú)進(jìn)行檢查,正確時(shí)返回true,錯(cuò)誤時(shí)返回false,這個(gè)方法在命令行中用于測試,檢查對(duì)txt數(shù)獨(dú)中求解時(shí),是否有錯(cuò)誤。
/**
* @Title: checkSolution
* @Description: 檢查結(jié)果
* @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: 檢查數(shù)獨(dú)答案是否正確
* @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;
}
測試
因?yàn)镚UI項(xiàng)目中,除了UI部分代碼,都是在命令行中經(jīng)過測試的代碼,所以只進(jìn)行簡單的系統(tǒng)測試,檢測頁面的響應(yīng)、監(jiān)聽等是否正常。
編號(hào)
操作
預(yù)期結(jié)果
實(shí)際結(jié)果
狀態(tài)
1
頁面有空位,點(diǎn)擊提交
未完成彈窗
未完成彈窗
通過
2
頁面沒有空位,存在錯(cuò)誤,點(diǎn)擊提交
錯(cuò)誤彈窗
錯(cuò)誤彈窗
通過
3
正確完成數(shù)獨(dú),點(diǎn)擊提交
正確彈窗
計(jì)時(shí)停止
正確彈窗
計(jì)時(shí)停止
通過
4
點(diǎn)擊查看答案
顯示答案
計(jì)時(shí)停止
顯示答案
計(jì)時(shí)停止
通過
5
點(diǎn)擊退出
退出程序
退出程序
通過
6
點(diǎn)擊新游戲
開始新游戲
開始新游戲
通過
7
在空位輸入非數(shù)字字符
輸不進(jìn)去
輸不進(jìn)去
通過
8
在空位輸入數(shù)字字符
空位顯示該數(shù)字
空位顯示該數(shù)字
通過
9
點(diǎn)擊查看答案以后,點(diǎn)擊提交
正確彈窗
正確彈窗
通過
10
點(diǎn)擊關(guān)于
信息彈窗
信息彈窗
通過
11
點(diǎn)擊幫助
幫助彈窗
幫助彈窗
通過
簡要開發(fā)過程
時(shí)間
內(nèi)容
2019年12月19日 - 2019年12月20日
需求分析、概要設(shè)計(jì)
2019年12月26日 - 2020年1月1日
基本完成命令行功能
2019年12月26日 - 2020年1月1日
開始單元測試
2020年1月2日 - 2020年1月3日
修改算法、對(duì)代碼結(jié)構(gòu)進(jìn)行優(yōu)化,完成測試
2020年1月4日 - 2020年1月16日
代碼質(zhì)量檢測、UI編寫
2020年1月17日 - 2020年1月18日
博客優(yōu)化
總結(jié)
以上是生活随笔為你收集整理的java数独流程图_软件工程个人项目总结-数独的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle数据库视图有红叉,oracl
- 下一篇: jquery不同版本冲突导致低版本功能不