1. 程式人生 > >基於第二次作業數獨遊戲,新增GUI介面

基於第二次作業數獨遊戲,新增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=new
Random(); 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文件重新溫習,然後就進行寫程式,但是期間還是遇到了一下問題,比如:怎麼將棋盤進行挖空、怎麼新增事件監聽等,通過百度和問已經在工作的同學,然後將其解決了,在此感謝在百忙之中抽空出來幫我解決問題的同學,對他們的幫助表示感謝。通過此次作業,發現以前學的東西基本上都還給老師了,感覺有點羞愧,說明自己的動手能力還是比較差,本科期間所花時間在敲程式碼上還是比較少的,這也是現在我的一個主要問題,也是我現在需要加強改進的地方,加油吧。