2016-04-13 6 views
0

このプログラムは1か月のデバッグ後に書かれましたが、最終的には動作するようになりましたが、8クイーンの問題には1解決策があります。すべてのソリューションを印刷しますか?コードは参考になりますが、何を変更するのか、何を追加するのかだけを指摘できれば、私もそれを使用することができます。N Queensすべてのソリューション、現在表示中1

import java.util.Scanner; 
    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. 
     // ------------------------------------------------- 
     for(int j = 1; j < 8; j++) 
     { 
      for(int k = 1; k < 8; k++) //Sets every column in this row to 0 
      { 
       board[j][k] = 0; 
      } 
      //moves on to next row and repeats 
     } 
    } // 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). 
     // ------------------------------------------------- 
     placeQueens(1); 
     int N = board.length; 
     for (int i = 0; i < N; i++) { 
      for (int j = 0; j < N; j++) { 
       if (board[i][j] == 1) 
       { 
        System.out.print("Q "); 
       } 
       else 
       { 
        System.out.print("_|"); 
       } 
      } 
      System.out.println(); 
     } 
    } // 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. 
     // -------------------------------------------------- 
     row = index(row); 
     column = index(column); 
     board[row][column] = 1; //Queen placed on square 
    } // 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. 
     // -------------------------------------------------- 
     column = index(column); 
     for(int x = 0; x < 8 ; x++) 
     { 
      if(board[x][column] == 1) 
      { 
       board[x][column] = 0; 
       x = 8;  
      } 
     } 

    } // 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. 
     // -------------------------------------------------- 

     //Taking 1-8 & returning 0-7 to suite array 
     row = index(row); 
     column = index(column); 

     //Checks the rows & columns 
     //Rows 
     for(int i = 0; i < column && i < 8 && row < 8; i++) 
     { 
      //If there's a queen in that row, the queen is under attack 
      if(board[row][i] == 1) 
      { 
       return true; 
      } 
     } 
     //Column 

     for(int j = 0; j < row && j < 8 && column < 8; j++) 
     { 
      //If there's a queen in that column, the queen is under attack 
      if(board[j][column] == 1) 
      { 
       return true; 
      } 
     } 

     //Check diagonals 
     for(int i = row, j = column; i >= 0 && j >= 0 && i < 8 && j < 8; i--, j--) 
     { 
      //checks upper diagonal 
      if(board[i][j] == 1) 
      { 
       return true; 
      } 
     } 

     for(int i = row, j = column; i < board.length && j >= 0 && i < 8 && j < 8; i++, j--) 
     { 
      //checks lower diagonal 
      if(board[i][j] == 1) 
      { 
       return true; 
      } 
     } 
     //At this point the Queen is not being attacked 
     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 

    public static void main(String[] args) 
    { 
     Queens eight = new Queens(); 
     eight.displayBoard(); 
    } 
} // end Queens 

答えて

0

displayBoardは、あなたの運転ルーチンです。 1つのソリューションを表示した後に停止させるのではなく、のplaceQueensが続きますループでラップしての新しいソリューションを見つけることができます。

これは、placeQueensを前のボード状態から続ける必要があることを意味します。すでにこれは大きな成果を上げています。最後の列に当たったケースを処理するだけです。たとえば、8番目のクイーンを1スクエアの下に移動し、7番目のクイーンの次の法的位置に戻るか(8番目の他の正当な場所がないことを知っているので)続けます。

これを実行している間、placeQueensが各ソリューションだけでなく、が完了したの条件を返すことができるように、これらの2つのルーチン間のインターフェイスをわずかに変更する必要があります。これにより、のdisplayBoardがループから抜け出すようになりました(追加した新しいラッパー)。

移動するには十分な説明ですか? "そうでもない" コメントの後


EDIT ...

はおそらく、書くための最も簡単なラッパーはdisplayBoardになります。あなたはplaceQueens(1)を持っているトップ、で、代わりにそれが中断したところからピックアップするようplaceQueensを適応

col = 1 
while(placeQueens(col)) { 
    ... print the board as usual 
    ... remove 8th queen; mark its position as unusable (say, with a value of -1) 
    col = 8 
} 

を使用します。それは、同じ場所にその第八女王を置くことになるでしょう。スポットが使用不可とマークされていることが判明したら、マークをリセットして第7クイーンに戻します。この操作を続行すると、すべてのソリューションが見つかります。

これを行うにはよりクリーンな方法がありますが、私はこれがあなたの現在の組織を十分に保存していると思います。理想的には、プレース・アンド・プリント・プロセスを繰り返すドライバ・プログラムがありますが、これは主に命名と上位レベルの構成の問題です。

あなたは十分に動いていますか?

+0

私のコードで遊んでいたわけではありません。クイーンズを設定してからremoveQueenを設定してから新しい出力が見つかるまで何度か作業を続けると、出力を印刷できるようにすればいいと思います。もっと説明できますか?またはコードを助けてください。 – Anonymous

関連する問題