2010-11-09 88 views
3

我的一項家庭作業是使用二維數組來表示棋盤,以解決八皇后問題。我不斷收到一個索引出界失誤:8在我的 「isUnderAttack」 的方法在:用二維數組解決八皇后問題:IndexOutOfBounds error

if (board[row][j] == QUEEN) 

,並在我的 「placeQueen」 的方法在:

if (isUnderAttack(row, column)) { 

queenPlaced = placeQueens(column+1); 

我可能在哪裏出錯了?我會添加更多的標籤到這篇文章,但我是一個新用戶,我不能創建「新標籤」。抱歉!

這裏是我所創建的:

public class Queens { 
     // squares per row or column 
     public static final int BOARD_SIZE = 8; 

     // used to indicate an empty square 
     public static final int EMPTY = 0; 

     // used to indicate square contains a queen 
     public static final int QUEEN = 1; 

     private int board[][]; // chess board 
     public Queens() { 
     // ------------------------------------------------- 
     // Constructor: Creates an empty square board. 
     // ------------------------------------------------- 
     board = new int[BOARD_SIZE][BOARD_SIZE]; 
     } // end constructor   

     public void clearBoard() { 
     // ------------------------------------------------- 
     // Clears the board. 
     // Precondition: None. 
     // Postcondition: Sets all squares to EMPTY. 
     // ------------------------------------------------- 
     //loops through rows 
      for (int i = 0; i < BOARD_SIZE; i++){ 
       //loops through columns 
      for (int j = 0; j <BOARD_SIZE; j++){ 
       board[i][j] = EMPTY; 
      } 
     } 
     } // end clearBoard 

     public void displayBoard() { 
     // ------------------------------------------------- 
     // Displays the board. 
     // Precondition: None. 
     // Postcondition: Board is written to standard 
     // output; zero is an EMPTY square, one is a square 
     // containing a queen (QUEEN). 
     // ------------------------------------------------- 

      for (int i = 0; i < BOARD_SIZE; i++){ 
       System.out.println(""); 

      for (int j = 0; j <BOARD_SIZE; j++){ 
       System.out.print(board [i][j] + " "); 
      } 
      } 
     } // end displayBoard 

     public boolean placeQueens(int column) { 
     // ------------------------------------------------- 
     // Places queens in columns of the board beginning 
     // at the column specified. 
     // Precondition: Queens are placed correctly in 
     // columns 1 through column-1. 
     // Postcondition: If a solution is found, each 
     // column of the board contains one queen and method 
     // returns true; otherwise, returns false (no 
     // solution exists for a queen anywhere in column 
     // specified). 
     // ------------------------------------------------- 
     if (column > BOARD_SIZE) { 
      return true; // base case 
     } 
     else { 
      boolean queenPlaced = false; 
      int row = 1; // number of square in column 

      while (!queenPlaced && (row <= BOARD_SIZE)) { 
      // if square can be attacked 
      if (isUnderAttack(row, column)) { 
       ++row; // consider next square in column 
      } // end if 
      else { // place queen and consider next column 
       setQueen(row, column); 
       queenPlaced = placeQueens(column+1); 
       // if no queen is possible in next column, 
       if (!queenPlaced) { 
       // backtrack: remove queen placed earlier 
       // and try next square in column 
       removeQueen(row, column); 
       ++row; 
       } // end if 
      } // end if 
      } // end while 
      return queenPlaced; 
     } // end if 
     } // end placeQueens 

     private void setQueen(int row, int column) { 
     // -------------------------------------------------- 
     // Sets a queen at square indicated by row and 
     // column. 
     // Precondition: None. 
     // Postcondition: Sets the square on the board in a 
     // given row and column to QUEEN. 
     // -------------------------------------------------- 
     board [row][column] = QUEEN; 
     } // end setQueen 

     private void removeQueen(int row, int column) { 
     // -------------------------------------------------- 
     // Removes a queen at square indicated by row and 
     // column. 
     // Precondition: None. 
     // Postcondition: Sets the square on the board in a 
     // given row and column to EMPTY. 
     // -------------------------------------------------- 
     board [row][column] = EMPTY; 
     } // end removeQueen 

     private boolean isUnderAttack(int row, int column) { 
     // -------------------------------------------------- 
     // Determines whether the square on the board at a 
     // given row and column is under attack by any queens 
     // in the columns 1 through column-1. 
     // Precondition: Each column between 1 and column-1 
     // has a queen placed in a square at a specific row. 
     // None of these queens can be attacked by any other 
     // queen. 
     // Postcondition: If the designated square is under 
     // attack, returns true; otherwise, returns false. 
     // -------------------------------------------------- 
      //i = rows and j = columns 
      //---------------------------------------- 
      // 
      // Checks before and after square 
      // 
      //---------------------------------------- 

      //looks behind for queens 
      for (int j = 0; j < column; j++){ 
      if (board[row][j] == QUEEN) 
       return true; 
     } 
     //looks in front for queens 
     for (int j =column+1; j < BOARD_SIZE; j++){ 
      if(board[row][j] == QUEEN) 
       return true; 
     } 
     //----------------------------------------------------------------- 
     // 
     // Checks diagonally from square 
     // 
     //----------------------------------------------------------------- 
     for (int i = 1+row, j = 1+column; i < BOARD_SIZE && j < BOARD_SIZE; i++, j++){ 
      if (board[i][j] == QUEEN) 
       return true; 
     } 
     for (int i= 1-row, j = 1-column; i >= 0 && j >=0; i--, j--){ 
      if (board[i][j] == QUEEN) 
       return true; 
     } 
     for (int i= 1+row, j = 1-column; i < BOARD_SIZE && j >= 0; i++, j--){ 
      if (board[i][j] == QUEEN) 
       return true; 
     } 
     for (int i= 1-row, j = 1+column; i >= 0 && j < BOARD_SIZE; i--, j++){ 
      if (board[i][j] == QUEEN) 
       return true; 
     } 
     return false; 
     } // end isUnderAttack 

     private int index(int number) { 
     // -------------------------------------------------- 
     // Returns the array index that corresponds to 
     // a row or column number. 
     // Precondition: 1 <= number <= BOARD_SIZE. 
     // Postcondition: Returns adjusted index value. 
     // -------------------------------------------------- 
     return number -1; 
     } // end index 
    } // end Queens 
+1

使用調試器並逐步執行代碼。在isUnderAttack:8處注意'row','column','i'和'j'的值。 – 2010-11-09 05:01:59

+1

順便說一句,如果這是Java(確實看起來像它),請使用Javadocs而不是單行註釋:) – irrelephant 2010-11-09 05:09:02

+0

從來沒有真正使用Javadocs。我會研究它。謝謝! – Bell 2010-11-09 05:45:56

回答

3

改變這一行:

而{

到(queenPlaced & &(行< = BOARD_SIZE)!):

while(!queenPlaced & &(row < BOARD_SIZE)){

因爲BOARD_SIZE被定義爲8,這是數組大小(8x8),當它嘗試訪問board [8] [j]時,isUnderAttack()函數跳出邊界。它可以訪問0-7行,而不是8行。

另外,您可能需要更改剛剛在該行之上的行(int row = 1;),以將行設置爲0而不是1(假設您想要從第一行開始)。

+0

我嘗試了您的第一個建議,但沒有發現任何錯誤。儘管如此,仍然存在問題。雖然沒有任何錯誤,但現在我的棋盤不顯示任何皇后。然後我試着改變int行爲0,但得到錯誤。這是否意味着我錯誤地編寫了「isUnderAttack」方法? – Bell 2010-11-09 05:17:42

+1

很可能。我發現你在isUnderAttack()中有對角線檢查的邏輯錯誤。即,具有'int i = 1 - 行'或'1 - 列'的for循環。你會想將它們改爲'row_1'和'column_1',因爲它們在負範圍內開始(或最多2次迭代後),所以i或j變爲-1,在這種情況下for循環終止。 – Amy 2010-11-09 15:19:58

+0

我明白了。謝謝! – Bell 2010-11-09 17:11:26

0

由於您將您的皇后從左欄放置到右欄,因此右欄不應有任何皇后檢查。所以你可以消除所有的右側檢查。