java Writes Sudoku Calculator

Posted by shiznatix on Wed, 17 Jul 2019 20:02:35 +0200

Filling rules

Sudoku's game rules are simple: in nine nine nine palace grids, fill in the number of 1 to 9, so that each number in each row, column and nine palace grids only once can pass.

Mystery Solving Skills

The puzzle-solving skills of Sudoku can be divided into intuitive method and candidate number method.

The characteristics of intuitive method:

  1. It can be applied without any auxiliary tools. So when you want to play Sudoku puzzles in newspapers and magazines, you just need a pen to start.
  2. From the moment you receive the Sudoku puzzle, you can begin to solve it immediately.
  3. The first way to solve problems for beginners or without computer aids.
  4. Relatively speaking, the puzzle that can be solved is relatively simple.
  5. The main techniques are: unique solution, basic elimination, block elimination, residual solution, rectangular elimination and unit elimination.

The characteristics of candidate number method:

  1. The list of candidates needs to be established first, so when we play the Sudoku puzzles in newspapers and magazines, because the space is usually not too large, and the establishment of the list of candidates is very cumbersome, so we often need computer assistance, or use the paper of the method of candidates to solve problems.
  2. The list of candidates needs to be established first, so it takes a considerable time for the first solution to appear from the moment the Sudoku puzzle is received.
  3. High-order intuitive techniques or computer-aided primary problem-solving methods are required.
  4. Relatively speaking, the puzzles that can be solved are more complex.

Writing Calculate classes

The Calculate class is the most important part of this algorithm. For ease of use, many functions and variables are declared static. In the class, we will complete the filling and calculation of Sudoku spaces. And the Calculate class implements the Runnable interface:

Steps:

  1. Define the implementation Runnable interface.
  2. Overrides the run method in the Runnable interface, and stores the code to be run by the thread in the run method.
  3. Thread objects are created through Thread classes.
  4. Subclass objects of the Runnable interface are passed to the constructor of the Thread class as actual parameters.
  5. Call the start method of the Thread class to open the thread and call the Runnable interface subclass run method.

Let's start by introducing all the members of the Calculate class:

class Calculate implements Runnable {
    // boo is used to determine whether the lattice is empty
    public static boolean[][] boo = new boolean[9][9];

    //Calculate the value of the specified row
    public static int upRow = 0; 

    //Calculate the specified column value
    public static int upColumn = 0; 

    //The data in the nine palaces will be stored
    public static int[][] b = new int[9][9]; 

    //Find blanks that do not fill in values
    public static void flyBack(boolean[][] judge,int row,int column){}

    //Traversing through all possible values
    public static void arrayAdd(ArrayList<Integer> array,TreeSet<Integer> tree){} 
    public static ArrayList<Integer> assume(int row,int column){}

    //Add possible options for each cell
    public void run(){} 

    //Analysis of the Completion of the Nine Palaces
    public void judge(){}
}

Analysis:

  • Two-dimensional array boo is used to determine whether the lattice is empty. If you have already filled in the values, you don't need to fill in any more.
  • Two-dimensional data b will store the data in the nine palaces.
  • The flyBack function is used to find spaces that do not fill in values.
  • The arrayAdd function adds new values (1-9) to a row. If the data already exists, skip and continue assigning if not.
  • The idea of assume is to determine which values are not filled in the same row of nine palaces. Adding alternative values is the idea of candidate method.
  • The run function starts running the whole program and generates the final result.

2. Write flyBack() function

public static void flyBack(boolean[][] judge, int row, int column) {
    // Generate temporary variable s, as described below
    int s = column * 9 + row;
    s--;

    // The quotient value is actually the value of column.
    int quotient = s / 9;

    // Take the value of the remainder, actually take (row-1)%9
    int remainder = s % 9;

    // Judging whether conditions are met
    if (judge[remainder][quotient]) {
        flyBack(judge, remainder, quotient);
    } else {
        // Assignment to upRow
        upRow = remainder;
        // Assignment to upColumn
        upColumn = quotient;
    }
}

Let's analyze this code:

Quotient is quotient and remainder is remainder.

//Here is pseudocode
s=column*9+row
s--=(column*9+row)-1
quotient = s/9
         = ((column*9+row)-1)/9
         = column + (row-1)/9 // Because row-1<9,The division here retains only the integer part.
         = column
remainder=s%9
         = ((column*9+row)-1)%9
         = (row-1)%9 //column*9Can be9To be divisible by

After analysis, it can be seen that the function is to calculate the value of the previous row of elements in the same column. If it is empty, it is assigned to upRow and upColumn, and if it still satisfies the condition, it continues to recurse.

This code looks cumbersome, but it's actually looking for spaces that haven't been filled in yet.

3 Write arrayAdd() function

arrayAdd() fills in the value of a row and traverses all possible values.

public static void arrayAdd(ArrayList<Integer> array, TreeSet<Integer> tree) {
    // Traverse 1-10
    for (int z = 1; z < 10; z++) {
        // flag3 defaults to true to determine whether z meets the criteria
        boolean flag3 = true;

        // it is an iterator
        Iterator<Integer> it = tree.iterator();

        // tree continues traversing if it has not finished traversing
        while (it.hasNext()) {
            // Assign the values in the list to b
            int b = it.next().intValue();
            if (z == b) {
                flag3 = false;
                break;
            }
        }

        // If you judge that z has not appeared in tree, add it in
        if (flag3) {
            array.add(new Integer(z));
        }

        // Initialize flag3
        flag3 = true;
    }
}

Due to Sudoku rule, each row and column can not be duplicated, so fill in the arrayAdd() function to add elements that are not in the tree, and if there is one, skip it.

4 Write assume() function

The purpose of this function is to analyze the possible solutions of each lattice and put them into an array. Then the run() function calls it to analyze the possible solutions.

public static ArrayList<Integer> assume(int row, int column) {
    // Create array
    ArrayList<Integer> array = new ArrayList<Integer>();
    TreeSet<Integer> tree = new TreeSet<Integer>();

    // Adding other element values to the same column
    for (int a = 0; a<9; a++) { 

        // If the lattice is not empty, add it to tree
        if (a != column && b[row][a] != 0) { 
            tree.add(new Integer(b[row][a]));
        }
    }

    // Adding other peer elements
    for (int c=0; c<9; c++) {

        // If the lattice satisfies the addition, it is added to tree
        if (c != row && b[c][column] != 0) {
            tree.add(new Integer(b[c][column]));
        }
    }

    // In this paper, integer division is used to retain the feature of integer only, and to obtain the rows of elements in the same small nine-grid.
    for (int a = (row/3)*3; a<(row/3+1)*3; a++)
    {
        // Get columns of elements in the same Nine-palace lattice
        for (int c = (column/3)*3; c < (column/3 + 1)*3; c++) {
            // If all elements satisfy the criteria, they are added to tree
            if ((!(a == row && c == column)) && b[a][c] != 0) {
                tree.add(new Integer(b[a][c]));
            }
        }
    }
    arrayAdd(array, tree);
    return array;
}

In order to improve the efficiency of the algorithm, we divide the Great Nine Palace into nine Little Nine Palaces. The main purpose is to analyze which values have been filled in the same small Nine Palaces in the same row. Then we call the arrayAdd() function to add the alternative values of the lattice.

5 Write run() function

run() is used for assignment calculation, and then the arrayAdd() function and assume() function are called to judge.

public void run() {
    // Initialize variable rows, columns
    int row = 0,column = 0; 

    // flag is used to determine whether the grid is filled correctly
    boolean flag = true;
    for (int a = 0; a < 9; a++) {
        for (int c = 0; c < 9; c++) {
            if (b[a][c] != 0) {
                /* boo The purpose is to find the blanks that fill in the data.
                *  Spaces filled in data are puzzles, and we need to solve puzzles based on this information.
                */
                boo[a][c] = true;
            } else {
                // A blank grid is the part of the data that needs to be filled in.
                boo[a][c] = false;
            }
        }
    }

    /* arraylist It is a two-dimensional sequence with each value being an array pointer.
    *  The possible solutions of the lattice are stored. When one solution is wrong, the next solution is called.
    * This is also the Sudoku method introduced earlier.
    */
    ArrayList<Integer>[][] utilization = new ArrayList[9][9];

    while (column < 9) {
        if (flag == true) {
            row = 0;
        }
        while (row < 9) {
            if (b[row][column] == 0) {
                if (flag) {
                    ArrayList<Integer> list = assume(row, column);//
                    utilization[row][column] = list;
                }

                // If no possible solution is found to indicate that the previous value is incorrect, the lattice is modified by going back to the previous one.
                if (utilization[row][column].isEmpty()) {
                    // Call the flyBack function to find the right row and column
                    flyBack(boo, row, column); 

                    // Return row to the appropriate seat
                    row = upRow;

                    // Return column to the appropriate seat
                    column = upColumn;

                    // Initialization of problematic lattices
                    b[row][column] = 0;
                    column--;
                    flag = false;
                    break;
                } else {
                    // Assign the first value of the alternative array to b
                    b[row][column] = utilization[row][column].get(0);

                    // Because the above value has been assigned, the first value is deleted.
                    utilization[row][column].remove(0);
                    flag = true;

                    //Determine whether all the cells are filled in correctly, and then output the correct results to the screen.
                    judge();
                }
            } else {
                // If r is false, indicating that there is still a grid that does not fill in the data, continue traversing
                flag = true;
            }
        row++;
        }
        column++;
    }
}

Where we fill in the blanks in the run() function, our idea is to analyze lines by lines, and each point may have several values. We use an array utilizationto store all possible values. On the basis of this value, we fill in the next blank. When we fill in the blanks, we go back here and fill in the blanks as utilization. The next value in the array.

6. Write judgement function judge()

public void judge()
{
    boolean r = true;

    // Find the grid that hasn't filled in the data yet
    for (int a1 = 0; a1 < 9; a1++) {
        for (int b1 = 0; b1 < 9; b1++) {
            if (r == false) {
                break;
            }

            // If b[a1][b1] needs to be calculated, it is extracted.
            if (b[a1][b1] == 0) {
                r = false;
            }
        }
    }

    // If r is true, then all the lattices are filled with data, indicating that the Nine-palace lattice is complete, and the output results are on the screen.
    if (r) { 
        for (int a1 = 0; a1 < 9; a1++) {
            for (int b1 = 0; b1 < 9; b1++) {
                Myframe.filed[a1][b1].setText(b[a1][b1] + "");
            }
        }
    }
}

Writing MyFrame classes

Because our structure is nine TextField plus two button controls, calculate and close. Based on these requirements, the contents are as follows:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeSet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

// Inheritance interface class
class Myframe extends JFrame {
    public static Object obj = new Object();
    // Creating the Nine Palace Interface
    public final static JTextField[][] filed = new JTextField[9][9];

    public Myframe() {
        // Initialize the interface so that all cells are empty
        for (int a = 0; a < 9; a++) {
            for (int b = 0; b < 9; b++) {
                filed[a][b] = new JTextField();
                filed[a][b].setText("");
            }
        }

        // Write layout, add textfield to layout
        JPanel jpan = new JPanel();
        jpan.setLayout(new GridLayout(9, 9));
        for (int a = 8; a > -1; a--) {
            for (int b = 0; b < 9; b++) {
                jpan.add(filed[b][a]);
            }
        }

        // The interface layout is centered
        add(jpan, BorderLayout.CENTER);
        JPanel jpb = new JPanel();

        // Set two buttons to calculate and exit
        JButton button1 = new JButton("calc");
        JButton button2 = new JButton("close");

        // Add buttons to the interface
        jpb.add(button1);
        jpb.add(button2);

        // To add a listener to a button is to add an event response function
        button1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                synchronized (obj) {
                    for (int a = 0; a < 9; a++) {
                        for (int b3 = 0; b3 < 9; b3++) {
                            int pp = 0;
                            // Get the values of the filled data in the Nine Palaces. These are the puzzles.
                            if (!(filed[a][b3].getText().trim().equals(""))) {
                                pp = Integer.parseInt(filed[a][b3].getText()
                                        .trim());
                                Calculate.b[a][b3] = pp;
                            }
                        }
                    }
                }

                synchronized (obj) {
                    // Open Threads to Calculate Nine-Palace Answers
                    new Thread(new Calculate()).start();
                }
            }
        });

        // button2 is very simple. Call the api to close the program
        button2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                System.exit(0);
            }
        });

        // Setting the layout of the interface
        add(jpb, BorderLayout.SOUTH);
    }
}

We add a listener to the button to obtain the interface information, generate the calculation results and close the program.

3. Writing Main Function

public class Sudoku{
    public static void main(String[] args) {
        Myframe myf=new Myframe();
        myf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Set the name of the main interface
        myf.setTitle("sudoku");

        //Setting the size of the interface
        myf.setSize(500,500);

        //Setting the main program to be visible
        myf.setVisible(true);
    }
}

The complete code is as follows:

http://labfile.oss.aliyuncs.com/courses/704/Sudoku.java

After the code is written, it starts compiling and running.

javac Sudoku.java  //A mistake will be reported here. It doesn't matter. It runs directly.
java Sudoku

Compilation rendering:

Operation effect diagram:

3.1 Solving Practical Puzzles

Introduce the topic into our program, and you will get the result soon. Applaud for your success!

Topics: Java