基于上次数独基础优化,并添加GUI界面

GUI界面:

package cn.sf.sudoku1;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;

public class GUI implements ActionListener {
    JButton submit = new JButton("Submit");
    JLabel CorrOrWrong = new JLabel("---");
    private static int[][] array;
    private static int[][] sudoku;
    private static JTextField[][] index = new JTextField[9][9];
    //UI界面
    public GUI (){
        JFrame frame = new JFrame("Sudoku");
        frame.setSize(500,500);
        submit.addActionListener(this);
        JPanel board = new JPanel();
        JPanel panel = new JPanel();
        board.setLayout(new GridLayout (9,9));
        for (int i =0;i<9;i++)
            for (int j=0;j<9;j++){
                index[i][j]=new JTextField(1);
                index[i][j].setText(""+sudoku[i][j]);
                if (sudoku[i][j]!=0)
                    index[i][j].setEditable(false);
                board.add(index[i][j]);
            }
        frame.getContentPane().add(board);
        frame.getContentPane().add(submit,"South");
        frame.getContentPane().add(CorrOrWrong, "North");
        frame.setVisible(true);
    }
    
    public void actionPerformed(ActionEvent e){
        if (e.getSource() == submit)
        {
            int[][] temp=submit();
            write(temp);
            try {
                Thread.sleep(2000);
            } catch (InterruptedException r) {
                r.printStackTrace();
            }
            if(testSudoku()) CorrOrWrong.setText("Correct!");
            else CorrOrWrong.setText("Wrong!");
        }
    }
    
    public boolean testSudoku() {
        return SudokuChecker.main(null);
    }
    
    public static int[][] submit(){
        int[][]result = new int[9][9];
        for (int i =0;i<9;i++)
            for (int j=0;j<9;j++){
                try {
                result[i][j]=Integer.parseInt(index[i][j].getText());
                }catch (Exception e){
                    result[i][j]=-1;
                }
            }
        return result;
    }
    
    public static int[][] readIn(){
        int[][] array = new int [9][9];
        int x=0;
        try
          {
             BufferedReader br = new BufferedReader(new FileReader("sudoku.txt"));
             String s;
             while ((s = br.readLine())!= null)
             {
                String[] parts = s.split(" ");
                for (int y=0;y<9;y++)
                    array[x][y]=Integer.parseInt(parts[y]);
                x++;
             }
             br.close();
          } catch (IOException e) 
            {
              System.out.println("ERROR");
            }
        return array;
    }
    
    public static void write(int[][] array){
        try
          {
             PrintWriter pw = new PrintWriter(new FileWriter("output.txt"));
             for (int i=0;i<9;i++)
             {
                String s="";
                for (int j=0;j<9;j++)
                    s+=array[i][j]+" ";
                pw.println(s);
             }
             pw.close();
          } catch (IOException e)
             {
                System.out.println("The following error occurred " + e);
             }
    }
    
    public static int[][] generate(){
        int[][] temp = new int [9][9];
        for (int i =0;i<9;i++)
            for (int j=0;j<9;j++){
                temp[i][j]=array[i][j];
            }
        int num=41;
        //输入41个数字
        while (num>0){
            int x=(int)(Math.random()*9);
            int y=(int)(Math.random()*9);
            if (temp[x][y]!=0){
                temp[x][y]=0;
                num--;
            }
        }
        return temp;
    }
    
    public static void main(String[] args) {
        //打开数独
        SudokuGenerator.main(null);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        array=readIn();
        sudoku=generate();
        for (int i = 0; i<9;i++){
            for (int j=0;j<9;j++)
                System.out.print(array[i][j] + " ");
            System.out.println();
        }
        new GUI();
    }

}

游戏运行检查:

package cn.sf.sudoku1;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class SudokuChecker{
    private static int [] temp = new int [9];
    private static int [][]sudoku = new int [9][9];
    
    private static int RowCheck ( int[][] x) {
      for (int i=0; i<9; i++) {
        for (int j= 0; j<9; j++)
          temp[j] = x[i][j];
                            
        if ( Check (temp) == 0 ) return 0;
      }
      return 1;
    }
    
    //主检查功能                                                               
    private static int Check (int[] y) {
      int lineartemp;
      for (int i=0; i<9; i++) {
        lineartemp = y[i];
        for (int j=i+1; j<9; j++) { //搜索重复
          if (y[j] ==  lineartemp)
            return 0;
              }
      }
      return 1;
    }
    
    //检查每列中的重复项
    private static int ColumnCheck ( int[][] x) {
      for (int i=0; i<9; i++) {
        for (int j= 0; j<9; j++)
          temp[j] = x[j][i];
                    
        if ( Check (temp) == 0 )
          return 0;
      }
      return 1;
    }                        
    
    //检查九个方格
    private static int SquaresCheck (int[][] x) {
    
    //行列索引
      int i,j,column,row,k;
            
      for (column=0; column <= 6; column += 3) {
        for (row=0; row <= 6; row += 3) {
          for (k=0, i=0; i<3; i++) {
            for (j=0; j<3; j++)
              temp[k++] = x[row+i][column+j];
          }
          if (Check(temp) ==0)
            return 0;                
        }
      }       
      return 1;
    }
    
    public static int[][] readIn(){
            int[][] array = new int [9][9];
            int x=0;
            try {
                 BufferedReader br = new BufferedReader(new FileReader("output.txt"));
                 String s;
                 while ((s = br.readLine())!= null)
                 {
                    String[] parts = s.split(" ");
                    for (int y=0;y<9;y++)
                        array[x][y]=Integer.parseInt(parts[y]);
                    x++;
                 }
                 br.close();
              } catch (IOException e) 
                {
                  System.out.println("ERROR");
                }
            return array;
    }
    
    public static boolean main(String [] args) {
      sudoku = SudokuChecker.readIn();     
      
      //通过
      if ( RowCheck(sudoku) == 0 || ColumnCheck(sudoku)==0 || SquaresCheck(sudoku)==0) 
          return false;
      
      //失败
      return true;
    }
}

异常检查及管理:

package cn.sf.sudoku1;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Random;
public class SudokuGenerator {
    private static Random rnd = new Random();
    
    public static void main(String[]args) {
        
        int[][] board;
        do {
            board = new int[9][9];
            board = SudokuGenerator.create(board, 0,0);
        } while(board == null);
        SudokuGenerator.createTXTFile(board);

    }
    
    private static int[][] create(int[][] ray, int row, int col){
        try{
            //用于检测数独谜题是否卡住的变量
            int countLoop = 0;
            do{
                if(countLoop ==10) {ray = cleanRow(ray, row); col = 0;}
                ray[row][col] = rnd.nextInt(9)+1; //return a number from 1 to 9.
                countLoop++;
            } while(!(testSquare(ray, row, col) && testColRow(ray, row, col))); 
            countLoop = 0;

            //如果完成,返回提供的数组
            if(row == 8 && col==8) return ray;
            
            //重启行
            if(col==8) return create(ray, row+1, 0);
            
            //重启列
            return create(ray, row, col+1);
        } catch (StackOverflowError e) {
            return null;
        } catch (NullPointerException e) {
            return null;
        }
    }
    //检查生成值是否在行列中
    private static boolean testColRow(int[][] ray, int row, int col) {
        //检查列
        for(int r = 0; r<row; r++) {
            if(ray[row][col] == ray[r][col]) return false;
        }
        //检查行
        for(int c = 0; c<col; c++) {
            if(ray[row][col] == ray[row][c]) return false;    
        }
        return true;
    }
    
    //检查生成值是否在方块中
    private static boolean testSquare(int[][] ray, int row, int col) {
        //每个元素起始值
        int rStart = 0, cStart = 0;
        //给每个元素设值
        if(row/3 == 0 && col/3 == 0) {rStart = 0; cStart = 0;}        //A
        else if(row/3 == 0 && col/3 == 1) {rStart = 0; cStart = 3;} //B
        else if(row/3 == 0 && col/3 == 2) {rStart = 0; cStart = 6;} //C
        else if(row/3 == 1 && col/3 == 0) {rStart = 3; cStart = 0;} //D
        else if(row/3 == 1 && col/3 == 1) {rStart = 3; cStart = 3;} //E
        else if(row/3 == 1 && col/3 == 2) {rStart = 3; cStart = 6;} //F
        else if(row/3 == 2 && col/3 == 0) {rStart = 6; cStart = 0;} //G
        else if(row/3 == 2 && col/3 == 1) {rStart = 6; cStart = 3;} //H
        else {rStart = 6; cStart = 6;} //I
        
        for(int r = rStart; r<(rStart+3); r++){
            for(int c = cStart; c<(cStart+3); c++){
                if(!(row==r && col == c) && ray[row][col] == ray[r][c]) return false;    
            }
        }
        return true;
    }
    
    public static void toConsole(int[][] ray) {
        for(int r = 0; r<9; r++) {
            for(int c = 0; c<9; c++) {
                System.out.print(ray[r][c] + " ");
            }
            System.out.println();
        }
    }
    
    //卡住时清理行
    private static int[][] cleanRow(int[][] ray, int rInt) {
        int[][] newAr = new int[9][9];
        for(int c = 0; c<9; c++) {
            for(int r = 0; r<rInt; r++) {
                newAr[r][c] = ray[r][c];
            }
        }
        return newAr;
    }
    
    public static void createTXTFile(int[][] ray) {
        try {
            PrintWriter writer = new PrintWriter("sudoku.txt", "UTF-8");
            for(int r = 0; r<9; r++) {
                for(int c = 0; c<9; c++) {
                    writer.print(ray[r][c]+ " ");
                }
                writer.println("");
            }
            writer.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }    
    }
}

接下来则是运行效果(使用说明):

设定预先值为41个。

请在空格处填充数字,

输入错误的话上方会提示输入有误。

 

输入正确的话也会显示“恭喜您输入正确!”

该程序运行顺利,并且代码已经长传至coding,传送门是:   https://coding.net/u/dhlg_1810812006/p/sudikutest/git/tree/master

由于这次基于上一次要求更多,要多加很多判断。所以在网上也看了很多资料,也问了问Java能力比较好的朋友,解决一些不懂的问题,对文件输入输出流也更掌握了点,另外各种逻辑的判断也有所感悟,程序是一个很严谨的事情,每个细节都可能是造成程序错误的原因,让我对细节的把我也更加上心。程序缺点就是没有自动修正功能,以后有机会再去改进。

原文地址:https://www.cnblogs.com/gordonsong/p/9794639.html