【发布时间】:2016-07-11 07:20:01
【问题描述】:
我正在尝试递归地实现骑士之旅。下面是我的代码。 为简单起见,我选择了 5x5 板。我的目标是打印出正确的骑士位置,并可能在打印语句的同时显示回溯。
class Knight
{
public boolean[][] board = new boolean[5][5];
public final int SQUARES = 5*5-1;
public Knight()
{
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
board[i][j] = false;
}
public boolean tour(int x, int y, int visitedX, int visitedY,int n)// x,y coords, just visited x,y and counter n
{
if(x>=5||y>=5||x<0||y<0){ //out of bounds
System.out.println("Visited "+x+", "+y+" Out of bounds");
System.out.println("Back to "+visitedX+", "+visitedY);
return false;
}
else{
if(board[x][y] == true)
{return false;}
if(board[x][y]!=true){
boolean result = false;
board[x][y]=true;
System.out.println("Visited "+x+", "+y);
result = tour(x+2,y+1,x,y,n+1);
result = tour(x+2,y-1,x,y,n+1);
result = tour(x+1,y-2,x,y,n+1);
result = tour(x-1,y-2,x,y,n+1);
result = tour(x+1,y+2,x,y,n+1);
result = tour(x-1,y+2,x,y,n+1);
result = tour(x-2,y-1,x,y,n+1);
result = tour(x-2,y+1,x,y,n+1);
}
}
return false;
}
}
public class KnightTApp {
public static void main(String[] args) {
Knight k = new Knight();
k.tour(0,0,0,0,0);
}
}
部分打印输出
Visited 4, 0
Visited 6, 1 Out of bounds
Back to 4, 0
Visited 6, -1 Out of bounds
Back to 4, 0
Visited 5, -2 Out of bounds
Back to 4, 0
Visited 3, -2 Out of bounds
Back to 4, 0
Visited 5, 2 Out of bounds
Back to 4, 0
Visited 2, -1 Out of bounds
Back to 4, 0
Visited 2, 0
我的问题是在这个过程的中间,我在索引 4,0 处遇到了一个死胡同(不是所有的方块都被覆盖,但我无法进行合法的移动)。而且由于我没有包含任何 回溯 行。它只是跳转到索引 2,0,这甚至不是合法的骑士移动。
我的问题是如何用 if 语句表达死胡同?我想我应该将递归设置为某种布尔值并从那里开始,但我不知道该怎么做。
并且还使用递归与使用 DFS(深度优先搜索)相同,因为它们基本上具有相同的想法?
提前谢谢你。
【问题讨论】:
-
从技术上讲,由于您使用的是递归搜索,因此该函数的任何返回都将是“回溯”。但是由于您从不从
tour()返回除false以外的任何内容,因此您无法在调用树上发出成功/失败的信号。你只会说“失败”。 -
我不确定如何在代码中表达这种情况。我知道获胜条件是所有方格都被访问,但我该如何表达呢?
-
我想一旦我弄清楚如何表达死胡同的情况,我会将counter部分设置为“true”的结果
-
您可以跟踪游戏板。对于每个 tour() 调用,您都会在棋盘中记录该移动,当棋盘填满时,您开始返回 true 备份树。如果你走到了死胡同并且板子没有满,那么这是一个失败的分支,你返回 false。
-
没错!但我怎么知道这是一个死胡同?我的意思是我当然可以从打印输出中看出,但我希望代码知道这是一个死胡同并从那里重新跟踪..
标签: java recursion knights-tour