1

私のプログラミング コースでは、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
4

2 に答える 2

1

あなたの allTaken メソッドは、本来あるべきことをしていないようです。

私の理解では、スロット マトリックス全体をトラバースし、1 から 9 までの各数字の 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

ただし、番号が見つかったら最初から検索を再開しないため、これは機能しません。たとえば、行列の位置 [8][8] にのみ 1 があると仮定すると、y と z のループが終了しているため、ループはどこにも 2、3、またはその他の数値を見つけられません。

考えられる修正の 1 つは、行列で遭遇したすべての一意の数値を追跡し (それらをセットに格納できます)、セットのサイズが 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;
}

これを行っても、アルゴリズムが効率的であると期待するべきではありません。数独をランダムに埋めることは、ほとんどの場合うまくいきません。

于 2012-01-19T14:54:43.040 に答える
0

問題は、セルの列または行のどこかに既にあるため、数値が収まらないセルに到達すると、taken常に真であり、無期限にループすることです。

また、ランダムを使用する理由がまったくわかりません。この方法では、同じ数値を何度もチェックして計算時間を無駄にしています。

まだセルをテストしておらず、途中でまだ使用されていない数値のリストを使用することをお勧めします。

また、あなたの 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;
}

ここから行って、どこまで行くか見てみましょう。

于 2012-01-19T15:01:41.153 に答える