2010-11-09 87 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

由于您将您的皇后从左栏放置到右栏,因此右栏不应有任何皇后检查。所以你可以消除所有的右侧检查。