8皇后需要重新启动全板而没有8个皇后

时间:2014-11-25 22:32:56

标签: java algorithm

所以我写了一个代码,它将继续将棋枰放在国际象棋棋盘上,直到没有更多可能的棋盘空间,女王可以坐下而不被另一位女王带走。问题是我的棋盘应该有8个皇后当它完成但我的主板上有5个(我的主板也不再有任何空间我可以放置一个女王)我想知道如何(使用尽可能多的我当前的代码) )有没有办法允许我的算法重新启动,当我到达一个我尚未在董事会上有8个皇后但已涵盖所有可能位置的点?

这是我的代码/输出:

public class Driver {

    public static void main(String[] args) {

        Driver run = new Driver();
        run.it();

    }

    public void it() {

        Tester test = new Tester();
        test.fillBoard();
        test.placeQueens();
        test.printBoard();

    }

}


public class Tester {

    public char [][] board = new char [8][8];

    public void fillBoard() {

        for(int i = 0; i < 8; i++) {

            for(int j = 0; j < 8; j++) {

                board[i][j] =' ';

            }

        }

    }

    public boolean checkUp(int row , int col) {

        if (((row < 0) || (row > 7)) || ((col > 7) || (col < 0))) {

            return true;

            } else {

            if (board[row][col] == 'Q') {

                return false;

            } else {

                return checkUp(row - 1, col);

            }

        }
    }

    public boolean checkDown(int row , int col) {

        if (((row < 0) || (row > 7)) || ((col > 7) || (col < 0))) {

            return true;

        } else {

            if (board[row][col] == 'Q') {

                return false;

            } else {

                return checkDown(row + 1, col);

            }

        }

    }

    public boolean checkUpAndRight(int row , int col) {

        if (((row < 0) || (row > 7)) || ((col > 7) || (col < 0))) {

            return true;

        } else {

            if (board[row][col] == 'Q') {

                return false;

            } else {

                return checkUpAndRight(row - 1, col - 1);

            }

        }

    }

    public boolean checkDownAndRight(int row , int col) {

        if (((row < 0) || (row > 7)) || ((col > 7) || (col < 0))) {

            return true;

        } else {

            if (board[row][col] == 'Q') {

                return false;

            } else {

                return checkDownAndRight(row + 1, col - 1);

            }

        }

    }   

    public boolean checkUpAndLeft(int row, int col) {

        if (((row < 0) || (row > 7)) || ((col > 7) || (col < 0))) {

            return true;

        } else {

            if (board[row][col] == 'Q') {

                return false;

            } else {

                return checkUpAndLeft(row - 1, col + 1);

            }

        }

    }

    public boolean checkDownAndLeft(int row , int col) {

        if (((row < 0) || (row > 7)) || ((col > 7) || (col < 0))) {

            return true;

        } else {

            if (board[row][col] == 'Q') {

                return false;

            } else {

                return checkDownAndLeft(row + 1, col + 1);

            }

        }

    }

    public boolean checkLeft(int row , int col) {

        if (((row < 0) || (row > 7)) || ((col > 7) || (col < 0))) {

            return true;

        } else {

            if (board[row][col] == 'Q') {

                return false;

            } else {

                return checkLeft(row, col + 1);

            }

        }

    }

    public boolean checkRight(int row , int col) {

        if (((row < 0) || (row > 7)) || ((col > 7) || (col < 0))) {

            return true;

        } else {

            if (board[row][col] == 'Q') {

                return false;

            } else {

                return checkRight(row, col - 1);

            }

        }

    }

    public boolean checkSpot(int row, int col) {

        if ((checkUp(row, col) == true) && (checkDown(row, col) == true) && 
        (checkUpAndRight(row, col) == true) && (checkDownAndRight(row, col) == true) && 
        (checkUpAndLeft(row, col) == true) && (checkDownAndLeft(row, col) == true) && 
        (checkLeft(row, col) == true) && (checkRight(row, col) == true)) {

            return true;

        } else {

            return false;

        }

    }


    public void placeQueens() {

        for(int col = 0; col < 8; col++) {

            for(int row = 0; row < 8; row++) {

                if(checkSpot(row, col) == true) {

                    board[row][col] = 'Q';

                }

            }

        }


    }

    public void printBoard() {

        String rtn = "";
        String newRow = "+---+---+---+---+---+---+---+---+\n";
        rtn += newRow;
        rtn += "| "+ board[0][0] +" | "+ board[0][1] +" | "+ board[0][2] +" | "+ board[0][3] +" | "
        + board[0][4] +" | "+ board[0][5] +" | "+ board[0][6] +" | "+ board[0][7] +" |\n";
        rtn += newRow;
        rtn += "| "+ board[1][0] +" | "+ board[1][1] +" | "+ board[1][2] +" | "+ board[1][3] +" | "
        + board[1][4] +" | "+ board[1][5] +" | "+ board[1][6] +" | "+ board[1][7] +" |\n";
        rtn += newRow;
        rtn += "| "+ board[2][0] +" | "+ board[2][1] +" | "+ board[2][2] +" | "+ board[2][3] +" | "
        + board[2][4] +" | "+ board[2][5] +" | "+ board[2][6] +" | "+ board[2][7] +" |\n";
        rtn += newRow;
        rtn += "| "+ board[3][0] +" | "+ board[3][1] +" | "+ board[3][2] +" | "+ board[3][3] +" | "
        + board[3][4] +" | "+ board[3][5] +" | "+ board[3][6] +" | "+ board[3][7] +" |\n";
        rtn += newRow;
        rtn += "| "+ board[4][0] +" | "+ board[4][1] +" | "+ board[4][2] +" | "+ board[4][3] +" | "
        + board[4][4] +" | "+ board[4][5] +" | "+ board[4][6] +" | "+ board[4][7] +" |\n";
        rtn += newRow;
        rtn += "| "+ board[5][0] +" | "+ board[5][1] +" | "+ board[5][2] +" | "+ board[5][3] +" | "
        + board[5][4] +" | "+ board[5][5] +" | "+ board[5][6] +" | "+ board[5][7] +" |\n";
        rtn += newRow;
        rtn += "| "+ board[6][0] +" | "+ board[6][1] +" | "+ board[6][2] +" | "+ board[6][3] +" | "
        + board[6][4] +" | "+ board[6][5] +" | "+ board[6][6] +" | "+ board[6][7] +" |\n";
        rtn += newRow;
        rtn += "| "+ board[7][0] +" | "+ board[7][1] +" | "+ board[7][2] +" | "+ board[7][3] +" | "
        + board[7][4] +" | "+ board[7][5] +" | "+ board[7][6] +" | "+ board[7][7] +" |\n";
        rtn += newRow;
        System.out.print(rtn);

    }
}


+---+---+---+---+---+---+---+---+
| Q |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+
|   |   |   | Q |   |   |   |   |
+---+---+---+---+---+---+---+---+
|   | Q |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+
|   |   |   |   | Q |   |   |   |
+---+---+---+---+---+---+---+---+
|   |   | Q |   |   |   |   |   |
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+

2 个答案:

答案 0 :(得分:1)

如果你放了一个女王并且事实证明你无法完成这个板,你应该删除女王。然后你应该继续前进到下一个单元格并再次尝试放置女王。

啊,但你怎么去安排下一个女王?你怎么能开始另一对嵌套循环来试试每个细胞?答案是递归,这是一种说法,你的函数会调用自己。

第一次调用函数时,它会查找可用的单元格。放置女王之后,它自称是第二位女王。该函数的第二个副本,一旦它放置了一个女王,就要求自己放置第三个女王。

递归何时停止?当最后一个女王被放置。该函数可以跟踪一个参数的剩余皇后数量,该参数在调用自身时递减。最初参数的值为8.在每次递归调用时,其值下降1.当它达到0时,所有的皇后都已放置,函数可以返回而不进行任何进一步的工作。

看看这个:

import java.lang.*;
import java.util.*;
import java.io.*;

public class EightQueens {

  char board[][] = new char[8][8];

  // Eight directions of attack:
  int dr[] = { -1, -1, -1, 0, 1, 1, 1, 0 },
      dc[] = { -1, 0, 1, 1, 1, 0, -1, -1 };

  public void clearBoard() {
    for (int r = 0; r < 8; ++r) {
      for (int c = 0; c < 8; ++c) {
        board[r][c] = ' ';
      }
    }
  }

  public void printBoard() {
    String separator = "+---+---+---+---+---+---+---+---+\n";
    StringBuffer buf = new StringBuffer();
    buf.append(separator);
    for (int r = 0; r < 8; ++r) {
      for (int c = 0; c < 8; ++c) {
        buf.append("| "+board[r][c]+" ");
      }
      buf.append("|\n"+separator);
    }
    System.out.println(buf.toString());
  }

  boolean available(int r, int c) {   // Returns true if no queen is
    for (int i = 0; i < 8; ++i) {     //  attacking this cell.
      int R = r, C = c;
      while (R >= 0 && R < 8 && C >= 0 && C < 8) {
        if (board[R][C] != ' ') {
          return false;
        }
        R += dr[i];                   // Use the directional arrays 
        C += dc[i];                   //  to go along the eight
      }                               //  lanes of attack.
    }
    return true;
  }

  boolean placeQueen(int count) {     // Returns true only on success.
    if (count == 0) {
      return true;                    // All queens have been placed.
    }
    for (int r = 0; r < 8; ++r) {
      for (int c = 0; c < 8; ++c) {
        if (available(r, c)) {
          board[r][c] = 'Q';          // Tentatively place a queen.
          if (placeQueen(count-1)) {  // Notice the decremented count.
            return true;              // If it worked, we're done.
          }
          board[r][c] = ' ';          // If not, remove the queen.
        }
      }
    }
    return false;
  }

  public static void main(String[] args) {
    EightQueens test = new EightQueens();
    test.clearBoard();
    test.placeQueen(8);
    test.printBoard();
  }
}

我的代码比你的短得多,因为我寻找减少重复的地方。将我的printBoard与您的placeQueen进行比较。看看我是如何实现细胞检查的。一个功能就足够了。

你最感兴趣的是递归函数{{1}}。研究它并使想法适应您自己的代码。

我看到你当前的细胞检查功能使用递归,所以你似乎熟悉一般的想法。只是你在错误的地方使用它。您可以使用嵌套循环来检查攻击通道,并在皇后放置函数中应用递归的概念。

答案 1 :(得分:0)

这是一个很好的链接,可以开始使用算法树和递归回溯 https://www.cs.utexas.edu/~scottm/cs307/handouts/recursiveBacktrackingExplanation.htm

基本上你不需要重启但是&#34;搜索&#34;对于每种可能的解决方案,以有序的方式,所以你知道你已经尝试过的董事会职位,你不会再尝试。