所以我写了一个代码,它将继续将棋枰放在国际象棋棋盘上,直到没有更多可能的棋盘空间,女王可以坐下而不被另一位女王带走。问题是我的棋盘应该有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 | | | | | |
+---+---+---+---+---+---+---+---+
| | | | | | | | |
+---+---+---+---+---+---+---+---+
| | | | | | | | |
+---+---+---+---+---+---+---+---+
| | | | | | | | |
+---+---+---+---+---+---+---+---+
答案 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;对于每种可能的解决方案,以有序的方式,所以你知道你已经尝试过的董事会职位,你不会再尝试。