我的随机数独生成器一直停止运行

发布于 2024-12-28 00:26:36 字数 4327 浏览 2 评论 0原文

对于我的编程课程,我决定在 GUI 中创建一个数独板。我已经为板的代码创建了一个类,每当需要填充的插槽无法填充任何东西时,板就会停止运行,并且我似乎无法重新启动它。有什么帮助吗?是什么导致它停滞不前?我该如何让它重新启动?

到目前为止我的代码:

public class GameCode{
    public static void main(String [] args){
        //Declare array for the game's code
        int [][] slot = new int[9][9];
        int [] slotSectorNums = new int[9];
        int num = 1;
        int tries = 0;
        boolean taken = false;
        boolean complete = true;

        do{
            //Reset slot array
            for (int x = 0; x < 9; x++){
                for (int y = 0; y < 9; y++){

                    //Clear the slot
                    slot[x][y] = 0;
                }//End of y for loop
            }//End of x for loop

            //Loop through rows of the array
            for (int row = 0; row < 9; row++){

                //Loop through columns of the array
                for (int column = 0; column < 9; column++){
                    tries = 0;

                    do{
                        tries++;

                        //Make the check-variable true
                        taken = false;

                        //Generate random integer for num
                        num = (int)(Math.random() * 9 + 1);

                        //Loop check within the row
                        for (int rowSlot = 0; rowSlot < 9; rowSlot++){

                            //Compare random number against row number
                            if (num == slot[rowSlot][column])
                                taken = true;
                        }//End of rowSlot loop

                        //Loop check within the column
                        for (int columnSlot = 0; columnSlot < 9; columnSlot++){

                            //Compare random number against column number
                            if(num == slot[row][columnSlot])
                                taken = true;
                        }
                    }while(taken == true && allTaken(row, column, slot) == false);
                    slot[row][column] = num;
                    temp(slot);
                }//End of column for loop
            }//End of row for loop
            temp(slot);
        }while(slot[8][8] != 0);
    }//End of main method

    public static int[] slotSectorNumDecide(int row, int column, int [][] slot){
        int [] slotNums = new int[9];
        int slotSectorRow = slotSectorRow(row) * 3;
        int slotSectorColumn = slotSectorColumn(column) * 3;
        int z = 0;

        //Loop for every slot
        for (int x = slotSectorRow; x < slotSectorRow + 2; x++){
            //Loop for every dimension
            for (int y = slotSectorColumn; y < slotSectorColumn + 2; y++){

                //Add the slot in the correct dimension to slotNums
                slotNums[z] = slot[x][y];

                //Increment the space in slotNums
                z++; 
            }//End of y for loop
        }//End of x for loop

        return slotNums;
    }//End of slot sectorSectorNumDecide

    public static int slotSectorRow(int row){
        int slotRow;
        slotRow = row / 3;
        System.out.println(row + " " + slotRow);

        return slotRow;
    }//End of slotSectorRow

    public static int slotSectorColumn(int column){
        int slotColumn;
        slotColumn = column / 3;
        System.out.println(column + " " + slotColumn);

        return slotColumn;
    }//End of slotSectorColumn method

    public static boolean allTaken(int row, int column, int [][] slot){
        int x = 1;

        for (int y = 0; y < 9 && x < 10; y++){
            for (int z = 0; z < 9 && x < 10; z++){
                if(slot[y][z] == x && x < 10)
                    x++;
            }//End of z for loop
        }//End of y for loop

        if (x == 10)
            return true;
        else
            return false;
    }//End of allTaken method

    public static void temp(int [][] slot){
        for (int x = 0; x < 9; x++){
            for (int y = 0; y < 9; y++){
                System.out.print("|" + slot[x][y]);
            }//End of y for loop
            System.out.println();
        }//End of x for loop
        System.out.println();
    }//End of temp method
}//End of class

For a programming course of mine, I have decided to create a Sudoku board in GUI. I've created a class for just the code of the board, and whenever the slot that needs to be filled can't be filled with anything, the board stalls, and I can't seem to make it restart. Any help? What is causing it to stall? How do I make it restart?

My code so far:

public class GameCode{
    public static void main(String [] args){
        //Declare array for the game's code
        int [][] slot = new int[9][9];
        int [] slotSectorNums = new int[9];
        int num = 1;
        int tries = 0;
        boolean taken = false;
        boolean complete = true;

        do{
            //Reset slot array
            for (int x = 0; x < 9; x++){
                for (int y = 0; y < 9; y++){

                    //Clear the slot
                    slot[x][y] = 0;
                }//End of y for loop
            }//End of x for loop

            //Loop through rows of the array
            for (int row = 0; row < 9; row++){

                //Loop through columns of the array
                for (int column = 0; column < 9; column++){
                    tries = 0;

                    do{
                        tries++;

                        //Make the check-variable true
                        taken = false;

                        //Generate random integer for num
                        num = (int)(Math.random() * 9 + 1);

                        //Loop check within the row
                        for (int rowSlot = 0; rowSlot < 9; rowSlot++){

                            //Compare random number against row number
                            if (num == slot[rowSlot][column])
                                taken = true;
                        }//End of rowSlot loop

                        //Loop check within the column
                        for (int columnSlot = 0; columnSlot < 9; columnSlot++){

                            //Compare random number against column number
                            if(num == slot[row][columnSlot])
                                taken = true;
                        }
                    }while(taken == true && allTaken(row, column, slot) == false);
                    slot[row][column] = num;
                    temp(slot);
                }//End of column for loop
            }//End of row for loop
            temp(slot);
        }while(slot[8][8] != 0);
    }//End of main method

    public static int[] slotSectorNumDecide(int row, int column, int [][] slot){
        int [] slotNums = new int[9];
        int slotSectorRow = slotSectorRow(row) * 3;
        int slotSectorColumn = slotSectorColumn(column) * 3;
        int z = 0;

        //Loop for every slot
        for (int x = slotSectorRow; x < slotSectorRow + 2; x++){
            //Loop for every dimension
            for (int y = slotSectorColumn; y < slotSectorColumn + 2; y++){

                //Add the slot in the correct dimension to slotNums
                slotNums[z] = slot[x][y];

                //Increment the space in slotNums
                z++; 
            }//End of y for loop
        }//End of x for loop

        return slotNums;
    }//End of slot sectorSectorNumDecide

    public static int slotSectorRow(int row){
        int slotRow;
        slotRow = row / 3;
        System.out.println(row + " " + slotRow);

        return slotRow;
    }//End of slotSectorRow

    public static int slotSectorColumn(int column){
        int slotColumn;
        slotColumn = column / 3;
        System.out.println(column + " " + slotColumn);

        return slotColumn;
    }//End of slotSectorColumn method

    public static boolean allTaken(int row, int column, int [][] slot){
        int x = 1;

        for (int y = 0; y < 9 && x < 10; y++){
            for (int z = 0; z < 9 && x < 10; z++){
                if(slot[y][z] == x && x < 10)
                    x++;
            }//End of z for loop
        }//End of y for loop

        if (x == 10)
            return true;
        else
            return false;
    }//End of allTaken method

    public static void temp(int [][] slot){
        for (int x = 0; x < 9; x++){
            for (int y = 0; y < 9; y++){
                System.out.print("|" + slot[x][y]);
            }//End of y for loop
            System.out.println();
        }//End of x for loop
        System.out.println();
    }//End of temp method
}//End of class

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷离° 2025-01-04 00:26:36

您的 allTaken 方法似乎没有执行应有的操作。

我的理解是,你遍历整个槽矩阵并尝试找到从 1 到 9 的每个数字出现的一次:

    for(int y = 0; y < 9 && x < 10; y++) {
        for(int z = 0; z < 9 && x < 10; z++) {
            if(slot[y][z] == x && x < 10)
                x++;
        }// End of z for loop
    }// End of y for loop

但这不起作用,因为一旦找到数字,你就不会从头开始搜索。例如,假设矩阵仅在位置 [8][8] 处有 1,则循环将不会在任何地方找到 2、3 或其他数字,因为 y 和 z 的循环已完成。

一个可能的修复方法是跟踪您在矩阵中遇到的所有唯一数字(您可以将它们存储在一个集合中),并在该集合的大小为 10 时停止。

但即使有了此修复程序,我也不确定您的算法会起作用:根据我对代码的理解, allTaken 函数应该验证所有数字是否不是出现在完整矩阵中,而是出现在给定的行或列(或 3 x 3 正方形)中。

在伪代码中,这将类似于:

boolean allTaken(int row, int column, int[][] slot) {
  Set<Integer> taken = Collections.emptySet();

  // Add elements from the row
  for(int x=0; x<9; x++) {
    taken.add(slot[row][x]);
  }

  // Add elements from the column
  for(int y=0; y<9; y++) {
    taken.add(slot[y][column]);
  }

  // Check the 3-by-3 square this row/column is in

  // sx and sy are the top-left coordinates of this square
  int sx = (row/3)*3; 
  int sy = (column/3)*3;
  for(int dx=0; dx<3; dx++) {
    for(int dy=0; dy<3; dy++) {
        taken.add(slot[sx+dx][sy+dy]);
    }
  }

  // All options are taken if the numbers from 1 to 9 appear in the set
  // Zero will be present too because slot[row][col] is zero.
  // So we expect 10 elements.
  return taken.size() == 10;
}

即使这样,您也不应该期望算法是有效的:随机填充数独在大多数情况下都不起作用。

Your allTaken method doesn't seem to be doing what it should be.

My understanding is that you traverse the whole slot matrix and try to find one occurence of each number from 1 to 9:

    for(int y = 0; y < 9 && x < 10; y++) {
        for(int z = 0; z < 9 && x < 10; z++) {
            if(slot[y][z] == x && x < 10)
                x++;
        }// End of z for loop
    }// End of y for loop

But this won't work because you don't restart the search from the start once you've found a number. For example assume that the matrix has a 1 only at position [8][8], then the loops won't find 2, 3 or other numbers anywhere because the loops for y and z are finished.

One possible fix would be to keep track of all the unique numbers you have encountered in the matrix (you can store them in a set), and stop whenever the set has size 10.

But even with this fix I'm not sure your algorithm will work: from what I understood of your code, the allTaken function should verify whether all of the numbers occur not in the full matrix, but in a given row, or column (or 3 by 3 square).

In pseudocode this would be something like:

boolean allTaken(int row, int column, int[][] slot) {
  Set<Integer> taken = Collections.emptySet();

  // Add elements from the row
  for(int x=0; x<9; x++) {
    taken.add(slot[row][x]);
  }

  // Add elements from the column
  for(int y=0; y<9; y++) {
    taken.add(slot[y][column]);
  }

  // Check the 3-by-3 square this row/column is in

  // sx and sy are the top-left coordinates of this square
  int sx = (row/3)*3; 
  int sy = (column/3)*3;
  for(int dx=0; dx<3; dx++) {
    for(int dy=0; dy<3; dy++) {
        taken.add(slot[sx+dx][sy+dy]);
    }
  }

  // All options are taken if the numbers from 1 to 9 appear in the set
  // Zero will be present too because slot[row][col] is zero.
  // So we expect 10 elements.
  return taken.size() == 10;
}

Even with this you shouldn't expect the algorithm to be efficient: filling sudoku randomly won't work most of the times.

不疑不惑不回忆 2025-01-04 00:26:36

问题是,一旦到达一个没有数字适合的单元格,因为它已经位于单元格列或行中的某个位置,则 taken 始终为 true,并且无限循环。

我也不明白为什么你会使用随机,这样你就会通过一遍又一遍地检查相同的数字来浪费计算时间。

您最好使用尚未测试单元格且尚未在途中某处使用的数字列表。

而且你的 allTaken 方法似乎还很遥远。

您可能想要这样的东西:

public static boolean allTaken(int row, int column, int [][] slot){
    int z = 0;
    boolean[] taken = new boolean[10];

    for (int x = 0; x < 9; x++) {
      taken[slot[row][x]] = true;
    }

    for (int x = 0; x < 9; x++) {
      taken[slot[x][column]] = true;
    }

    boolean f = true;
    for (boolean b : taken)
      f = f && b;

    return f;
}

从这里开始,看看您能走多远。

The problem is once you reach a cell where no number fits because it is already somewhere in the cells column or row takenis always true and you loop indefinitely.

I also don't see why you would use random at all, this way you are wasting computation time by checking the same numbers over and over.

You better work with a list of numbers you did not yet test for a cell and which are not yet used somewhere on the way.

Also it seems your allTaken method is way off.

You probably want something like this:

public static boolean allTaken(int row, int column, int [][] slot){
    int z = 0;
    boolean[] taken = new boolean[10];

    for (int x = 0; x < 9; x++) {
      taken[slot[row][x]] = true;
    }

    for (int x = 0; x < 9; x++) {
      taken[slot[x][column]] = true;
    }

    boolean f = true;
    for (boolean b : taken)
      f = f && b;

    return f;
}

Go from here and see how far you get.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文