2012-01-19 21 views
1

對於我的編程課程,我決定在GUI中創建一個Sudoku板。我已經爲電路板的代碼創建了一個類,只要需要填充的插槽不能填充任何東西,電路板就會停止工作,我似乎無法使其重新啓動。任何幫助?是什麼導致它失速?我如何讓它重新啓動?我的隨機數獨發生器保持失速

我迄今爲止代碼:

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 
+1

你是什麼意思,拖延?你的意思是它沒有找到解決方案?順便說一句:使用'Random.nextInt(9)'可能會快得多。 –

+1

您可以附加調試器和/或使用日誌記錄來確定失速發生的位置嗎? –

+0

通過拖延,我的意思是沒有輸出發生,並沒有找到解決方案(由於所有可用的號碼被採取)。 調試沒有說什麼。 –

回答

1

你allTaken方法似乎沒有做它應該是什麼。

我的理解是,你遍歷整個插槽矩陣,並試圖找到每個號碼的一個occurence從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,則由於y和z的環完成,所以環不會在任何地方找到2,3或其他數字。

一個可能的解決將是跟蹤所有你在矩陣(你可以將它們存儲在一組)所遇到的唯一編號,並停止只要設定有大小10

但即使有這樣的修復我不確定你的算法是否可行:從我所瞭解的代碼中,allTaken函數應該驗證所有數字是否不在全矩陣中,而是在給定的行或列中(或3乘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; 
} 

即使這樣,你不應該期望該算法是有效的:隨機填充數獨是行不通的大部分時間。

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; 
} 

去看看你走多遠。

+0

現在用我到目前爲止的代碼,它工作得很好。我現在唯一需要弄清楚的是如何讓它與slotSector匹配。非常感謝你幫助我! –

+0

我會說我留給你,練習。無論如何,基本上不是隻掃描單元行和列,而是使用相同的「採集」陣列掃描扇區。 – stryba