基于第二次作业数独游戏,添加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文档重新温习,然后就进行写程序,但是期间还是遇到了一下问题,比如:怎么将棋盘进行挖空、怎么添加事件监听等,通过百度和问已经在工作的同学,然后将其解决了,在此感谢在百忙之中抽空出来帮我解决问题的同学,对他们的帮助表示感谢。通过此次作业,发现以前学的东西基本上都还给老师了,感觉有点羞愧,说明自己的动手能力还是比较差,本科期间所花时间在敲代码上还是比较少的,这也是现在我的一个主要问题,也是我现在需要加强改进的地方,加油吧。

原文地址:https://www.cnblogs.com/AnanKing/p/9790623.html