java - 制作合适的 Java 数独生成器的问题

标签 java algorithm while-loop lwjgl sudoku

<分区>

这就是我得到的

package sud.util;

import java.util.Random;

public class SudoGrid {

    Random gen;

    private int[][] grid;
    private int[] fail;
    private int[]   succes;

    public void init(){
        gen = new Random();
        grid = new int[9][9];
        fail = new int[3];
        succes = new int[3];

        fail[0] = 0;
        fail[1] = 0;
        fail[2] = 0;

        succes[0] = 0;
        succes[1] = 0;
        succes[2] = 0;
    }

    public int[][] generate() {

        for (int x = 0; x < 9; x++) {
            for (int y = 0; y < 9; y++) {

                boolean isValid = false;


                do{
                    int num = gen.nextInt(9) + 1;


                    if ((checkRow(num, x) != true
                            || checkCol(num, y) != true
                            ||checkSection(num, x, y) != true)){

                        //System.out.println("Row  failed: "+fail[0]+" times, and succeeded:"+succes[0]+" times");
                        //System.out.println("Col  failed: "+fail[1]+" times, and succeeded:"+succes[1]+" times");
                        //System.out.println("Sec failed: "+fail[2]+" times, and succeeded:"+succes[2]+" times\n----------------------------");
                        printBlock();

                    }else if ((checkRow(num, x) == true
                            && checkCol(num, y) == true
                            &&checkSection(num, x, y) == true)){




                        grid[x][y] = num;

                        isValid = true;
                    }

                }while(isValid == false);
            }
        }
        System.out.println("\n######################################################");
        System.out.println("########################CHEESE########################");
        System.out.println("######################################################\n");
        printBlock();
        return grid;
    }

    private boolean checkRow(int num, int row) {//Check a specific row

        boolean valid = true;
        for (int c = 0; c < 9; c++) {
            if (grid[row][c] == num) {
                valid = false;

               break;
            }
        }
        if(valid == false){
            fail[0]++;
        }else{
            succes[0]++;
        }

        return valid;
    }

    private boolean checkCol(int num, int col) {//Checks a specific col

        boolean valid = true;
        for (int r = 0; r < 9; r++) {
            if (grid[r][col] == num) {
                valid = false;

                break;
            }
        }
        if(valid == false){
            fail[1]++;
        }else{
            succes[1]++;
        }
        return valid;
    }

    private boolean checkSection(int num, int xPos, int yPos) {//Checks a 3x3 square

        int[][] section = new int[3][3];
        section = getSection(xPos, yPos);

        boolean valid = true;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (section[i][j] == num) {
                    valid = false;
                  break;
                }
            }
        }
        if(valid == false){
            fail[2]++;
        }else{
            succes[2]++;
        }
        return valid;
    }


    private int[][] getSection(int xPos, int yPos) {

        int xIndex = 0;
        int yIndex = 0;
        int[][] section = new int[3][3];

        if (xPos == 0 || xPos == 3 || xPos == 6) {
            xIndex = xPos;
        } else if (xPos == 1 || xPos == 4 || xPos == 7) {
            xIndex = xPos - 1;
        } else if (xPos == 2 || xPos == 5 || xPos == 8) {
            xIndex = xPos - 2;
        }

        if (yPos == 0 || yPos == 3 || yPos == 6) {
            yIndex = yPos;
        } else if (yPos == 1 || yPos == 4 || yPos == 7) {
            yIndex = yPos - 1;
        } else if (yPos == 2 || yPos == 5 || yPos == 8) {
            yIndex = yPos - 2;
        }

        int i = 0;
        int j = 0;

        for (int x = xIndex; x < 3; x++) {
            for (int y = yIndex; y < 3; y++) {
                section[x][y] = grid[i][j];
                i++;
            }
            j++;
        }

        return section;

    }

    public void printBlock() {
        String str = "";
        for(int i = 0; i < 9; i++) { 
            for(int j = 0; j < 9; j++) { 
                str += " " + (grid[i][j]);
            }
            str += "\n";
        }
        System.out.println(str);
    }
}

这是 printBlock(); 一段时间后返回的内容

9 5 6 1 3 4 8 7 2
7 1 3 8 5 2 9 6 4
6 8 5 7 4 1 3 2 9
3 7 8 6 9 5 1 4 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0

我的部分检查有问题,但我似乎找不到。

感谢您的宝贵时间。

最佳答案

例如,当您遇到这样的场景时:

 1 2 3 | 4 5 6 | 7 8 9
 4 5 6 | 1 2 3 |

没有您可以在下一个单元格中填写的有效值。

要处理这个,你需要添加backtracking ,即,如果您找不到单元格的有效值,请返回并为之前生成的单元格尝试不同的值。

这样做的提示 - 考虑添加一个 bool tryCell(int x, int y) 函数来运行您的 do-while 循环,并在循环内调用 tryCell对于下一个单元格,只在 generate 中调用 tryCell(0,0)。如果这对您来说没有意义,我建议您在线寻找带回溯功能的数独生成器,应该有很多。

关于java - 制作合适的 Java 数独生成器的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18652607/

相关文章:

java - 从同一 session 同时请求同一端点会在 Play 中产生问题

python - Numpy:如何添加/加入切片对象?

php - 使用php + MySQLi取数据时使用while可以吗?

javascript - 文本!= ""是什么意思?

java - 错误 : base operand of ‘->’ has non-pointer type ‘JNIEnv’

java - 在 FFMPEG 写入文件时读取文件

algorithm - 购物车 bundle 的组合算法

java - 如何停止 JShell/Kulla 中的无限循环?

java - Java 中的类声明与 Kotlin 中的类声明

algorithm - 在列表中查找元素集,元素只能使用一次 - 如何处理算法