基於第二次作業數獨遊戲,新增GUI介面
基於第二次數獨遊戲,在此基礎上進行新增GUI介面,GUI介面程式碼如下:建立一個ShuduGUI類。
1 package sudoku; 2 import javax.swing.*; 3 import java.awt.*; 4 import java.awt.event.*; 5 import java.util.Random; 6 7 public class ShuduGUI extends JFrame{ 8 private static JTextField a[][]=new JTextField[9][9]; //儲存文字框中的數字 9 static int check[][]=new int[9][9]; //儲存輸入後的兩位陣列 10 GenerateNumber example=new GenerateNumber(); //產生數字 11 public int right[][]=example.GenerateNumberMatrix(); 12 public int rightans[][]; 13 private int[][] blank(int a[][]){ //挖空 14 Random c=newRandom(); 15 int a1,a2; 16 a1=c.nextInt(9); 17 a2=c.nextInt(9); 18 for(int i=0;i<100;i++) 19 { 20 a[a1][a2]=0; 21 a1=c.nextInt(9); 22 a2=c.nextInt(9); 23 } 24 return a; 25 }26 public ShuduGUI(){ //畫GUI介面 27 Container r=getContentPane(); 28 r.setLayout(new BorderLayout(2, 1)); //邊框佈局 29 JMenuItem jmiOk=new JMenuItem("提交"); //定義選單 30 JMenuItem jmiExplain=new JMenuItem("提示"); 31 JPanel panel=new JPanel(); //定義一個容器 32 panel.add(jmiOk); //將選單在容器內顯示 33 panel.add(jmiExplain); 34 JPanel p1=new JPanel(new GridLayout(9,9,5,5)); //定義9行9列的網格佈局 35 add(panel,BorderLayout.NORTH); //將選單放置在北面 36 add(p1,BorderLayout.CENTER); //將數字放置在正中間 37 rightans=blank(right); 38 for(int k=0;k<9;k ++) 39 { 40 for(int n=0;n<9;n++) 41 { 42 if(rightans[k][n]!= 0) 43 { 44 a[k][n]=new JTextField(""+rightans[k][n]); 45 a[k][n].setHorizontalAlignment(SwingConstants.CENTER);//將數字水平居中 46 a[k][n].setEditable(false); //只可顯示不可修改 47 p1.add(a[k][n]); //新增文字框 48 } 49 else 50 { 51 a[k][n]=new JTextField(); 52 a[k][n].setHorizontalAlignment(SwingConstants.CENTER); 53 p1.add(a[k][n]); 54 } 55 } 56 } 57 add(p1); //將數字面板顯示在容器裡 58 jmiOk.addActionListener(new ActionListener(){//匿名建立事件監聽器 59 @Override 60 public void actionPerformed(ActionEvent e) 61 { 62 if(gettext()==1) 63 { 64 if(judge()==true) 65 { 66 JOptionPane.showMessageDialog(null, "Your answer is right!","Result",JOptionPane.INFORMATION_MESSAGE); 67 } 68 else 69 { 70 JOptionPane.showMessageDialog(null, "Your answer is wrong!","Result",JOptionPane.INFORMATION_MESSAGE); 71 } 72 } 73 } 74 }); 75 explainListenerClass listener2=new explainListenerClass(); 76 jmiExplain.addActionListener(listener2); 77 messageListenerClass listener3=new messageListenerClass(); 78 } 79 static int gettext() //獲取挖空文字框的文字 內容 80 { 81 int i,j; 82 for(i=0;i<9;i++) 83 { 84 for(j=0;j<9;j++) 85 { 86 check[i][j]=0; 87 } 88 } 89 for(int k=0;k<9;k++) 90 { 91 for(int n=0;n<9;n++) 92 { 93 try //異常處理 94 { 95 check[k][n] = Integer.parseInt(a[k][n].getText()); 96 //將答案型別轉換之後傳給check 97 } 98 catch(NumberFormatException nfe) 99 { 100 JOptionPane.showMessageDialog(null,"資料中包括非數字,請重新輸入"); 101 return 0; 102 } 103 } 104 } 105 return 1; 106 } 107 public static boolean judge() //判斷輸入的答案是否正確 108 { 109 int i,j,k; 110 int [][]answer=check; 111 112 for(i=0;i<9;i++) 113 { 114 if(judge9(answer[i])==false) //判斷每列是否有重複數字 115 return false; 116 } 117 for(j =0;j<9;j++) //判斷每行是否有重複數字 118 { 119 120 int[] newAnswerColumn=new int[9]; 121 for(i =0;i<9;i++) 122 { 123 newAnswerColumn[i]=answer[i][j]; 124 } 125 if(judge9(newAnswerColumn)==false) 126 return false; 127 } 128 for(i=0;i<3;i++) //判斷每個小九宮格內是否有重複數字 129 { 130 for(j=0;j<3;j++) 131 { 132 k=0; 133 int[] newAnswer=new int[9]; 134 for(int m=i*3;m<i*3+3;m++) 135 { 136 for(int n=j*3;n<j*3+3;n++) 137 { 138 newAnswer[k]=answer[m][n]; 139 k++; 140 } 141 } 142 if(judge9(newAnswer)==false) 143 { 144 return false; 145 } 146 } 147 } 148 return true; 149 } 150 public static boolean judge9(int[] answer) 151 { 152 int i,j; 153 for(i=0;i<9;i++) 154 { 155 for(j=0;j<9;j++) 156 { 157 if(i==j) 158 continue; 159 if(answer[i]==answer[j]) //如果有重複的數字,返回false 160 { 161 return false; 162 } 163 } 164 } 165 return true; //沒有重複數字,返回true 166 } 167 168 public static void main(String[] args) { 169 // TODO 自動生成的方法存根 170 JFrame frame=new ShuduGUI(); 171 frame.setTitle("數獨遊戲"); 172 frame.setSize(600,900); 173 frame.setLocationRelativeTo(null); 174 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 175 frame.setVisible(true); 176 } 177 } 178 class explainListenerClass implements ActionListener{ //事件監聽器 179 @Override 180 public void actionPerformed(ActionEvent e){ 181 JOptionPane.showMessageDialog(null, "填入數字保證每行每列及每個小的九宮格內數字無重複","Explain",JOptionPane.INFORMATION_MESSAGE); 182 } 183 }
數獨棋盤(帶挖空)的生成程式碼如下:建立一個GenerateNumber類。
1 package sudoku; 2 import java.util.Random; 3 4 public class GenerateNumber{ 5 private Random random=new Random(); 6 private static final int MAXTIMES=220; 7 private int currentTimes=0; 8 public int[][] GenerateNumberMatrix(){ 9 // TODO 自動生成的方法存根 10 int[][] randomMatrix=new int[9][9]; 11 for (int row=0;row<9;row++){ 12 if (row==0){ 13 currentTimes=0; 14 randomMatrix[row]=buildRandomArray(); 15 } 16 else{ 17 int[] tempRandomArray=buildRandomArray(); 18 for (int col=0;col<9;col++){ 19 if (currentTimes<MAXTIMES){ 20 if (!isCandidateNmbFound(randomMatrix,tempRandomArray,row,col)){ 21 resetValuesInRowToZero(randomMatrix,row); 22 row-=1; 23 col=8; 24 tempRandomArray=buildRandomArray(); 25 } 26 } 27 else{ 28 row=-1; 29 col=8; 30 resetValuesToZeros(randomMatrix); 31 currentTimes=0; 32 } 33 } 34 } 35 } 36 return randomMatrix; 37 } 38 private void resetValuesInRowToZero(int[][] matrix,int row){ 39 // TODO 自動生成的方法存根 40 for (int j=0;j<9;j++){ 41 matrix[row][j]=0; 42 } 43 } 44 private void resetValuesToZeros(int[][] matrix){ 45 // TODO 自動生成的方法存根 46 for (int row=0;row<9;row++){ 47 for (int col=0;col<9;col++){ 48 matrix[row][col]=0; 49 } 50 } 51 } 52 private boolean isCandidateNmbFound(int[][] randomMatrix,int[] randomArray,int row,int col){ 53 // TODO 自動生成的方法存根 54 for (int i=0;i<9;i++){ 55 randomMatrix[row][col]=randomArray[i]; 56 if (noConflict(randomMatrix,row,col)){ 57 return true; 58 } 59 } 60 return false; 61 } 62 private boolean noConflict(int[][] candidateMatrix,int row,int col){ 63 // TODO 自動生成的方法存根 64 return noConflictInRow(candidateMatrix,row,col)&&noConflictInColumn(candidateMatrix,row,col) && noConflictInBlock(candidateMatrix, row, col); 65 } 66 private boolean noConflictInRow(int[][] candidateMatrix,int row,int col){ 67 // TODO 自動生成的方法存根 68 int currentValue=candidateMatrix[row][col]; 69 for (int colNum=0; colNum<col;colNum++){ 70 if (currentValue==candidateMatrix[row][colNum]){ 71 return false; 72 } 73 } 74 return true; 75 } 76 private boolean noConflictInColumn(int[][]candidateMatrix,int row,int col){ 77 // TODO 自動生成的方法存根 78 int currentValue=candidateMatrix[row][col]; 79 for (int rowNum=0;rowNum<row;rowNum++){ 80 if (currentValue==candidateMatrix[rowNum][col]){ 81 return false; 82 } 83 } 84 return true; 85 } 86 private boolean noConflictInBlock(int[][] candidateMatrix,int row,int col){ 87 // TODO 自動生成的方法存根 88 int baseRow=row/3*3; 89 int baseCol=col/3*3; 90 for (int rowNum=0;rowNum<8;rowNum++){ 91 if (candidateMatrix[baseRow+rowNum/3][baseCol+rowNum%3]==0){ 92 continue; 93 } 94 for (int colNum=rowNum+1;colNum<9;colNum++){ 95 if (candidateMatrix[baseRow+rowNum/3][baseCol+rowNum%3]==candidateMatrix[baseRow+colNum/3][baseCol+colNum%3]) 96 { 97 return false; 98 } 99 } 100 } 101 return true; 102 } 103 private int[] buildRandomArray(){ 104 // TODO 自動生成的方法存根 105 currentTimes++; 106 int[] array=new int[]{1,2,3,4,5,6,7,8,9}; 107 int randomInt = 0; 108 for (int i=0;i<20;i++){ 109 randomInt=random.nextInt(8)+1; 110 int temp=array[0]; 111 array[0]=array[randomInt]; 112 array[randomInt]=temp; 113 } 114 return array; 115 } 116 public int getCurrentTimes(){ 117 // TODO 自動生成的方法存根 118 return currentTimes; 119 } 120 public void setCurrentTimes(int currentTimes){ 121 // TODO 自動生成的方法存根 122 this.currentTimes=currentTimes; 123 } 124 }
執行效果截圖如下:如圖1所示,是執行效果圖,圖中有兩個按鈕,一個“提交”按鈕,一個“提示”按鈕,當答題者在空格區域內輸完數字解題完畢,點選“提交”按鈕,會立馬顯示答題者的答案正確與否,答錯了提示“Your answer is wrong!”,答對了提示“Your answer is right!”,如圖2所示,如果答題者未答完題就點選“提交”按鈕,系統會顯示“資料中包含非數字,請重新輸入”,你是不能進行提交的,必須答完將所有空格填滿才能進行提交,如圖3所示,;如果不會寫,點選“提示”按鈕,會提示你該怎麼填,其實這功能並未實現,點選“提示”按鈕,只會提示你“填入數字保證每行每列及每個小的九宮格內數字無重複”,如圖4所示。這提示對於答題者來說很雞肋,除非沒玩過數獨的人才有那麼一丁點作用。
圖1
圖2
圖3
圖4
備註:兩個程式的程式碼已上傳至coding:地址為:https://git.coding.net/AnanKing/ShuDu.git
2、程式執行的正確性以及效能分析:該遊戲的GUI介面執行顯示正常,有較為友好的遊戲說明,只能提示數獨題目中空格是否填滿,以及答案是否錯誤等,效能一般。 3、心得:在本次做題過程中,一共花了4~5天的時間才做完,其中遇到的問題還是有很多的,幸運的是,我都把它解決了,解決問題的途徑有兩種方式,一種是上網百度,另一種就是問已經在工作的同學。此次題目是在上一次的基礎上進行新增GUI介面,本科學習的時候,學了一點, 但是沒學的怎麼深,然後也就忘了,幸運的是,我大四校內生產實習的時候,結課的時候是完成一個五子棋小遊戲開發, 也是用java寫的,所以對畫GUI介面還是有點印象,然後把以前寫的程式碼找出來,然後看了一些時間,把以前遺忘的知識點回憶了一下,很多東西都已經忘的差不多, 然後又去檢視官網的API文件重新溫習,然後就進行寫程式,但是期間還是遇到了一下問題,比如:怎麼將棋盤進行挖空、怎麼新增事件監聽等,通過百度和問已經在工作的同學,然後將其解決了,在此感謝在百忙之中抽空出來幫我解決問題的同學,對他們的幫助表示感謝。通過此次作業,發現以前學的東西基本上都還給老師了,感覺有點羞愧,說明自己的動手能力還是比較差,本科期間所花時間在敲程式碼上還是比較少的,這也是現在我的一個主要問題,也是我現在需要加強改進的地方,加油吧。