我的骑士之旅算法可能正在无限循环上运行
这是我写的代码。
#include "genlib.h"
#include <iostream>
#include <math.h>
#include "vector.h"
struct square
{
int x;
int y;
};
bool knighttour(square start,int &counter,int cb[][8]);
Vector <square> generatemoves (square start);
void Marksquare(int &cb,int ctr);
void Unmarksquare(int &cb);
bool IsLegal(square a,int cb[][8]);
int main()
{
int chessboard[8][8];
for (int i=0;i<8;i++)
for (int j=0;j<8;j++)
chessboard[i][j]=-1;
int counter=1;
for (int i=0;i<8;i++){
for (int j=0;j<8;j++){
square temp;
temp.x=i;
temp.y=j;
if (knighttour(temp,counter,chessboard))
{
for (int k=0;k<8;k++){
cout<<chessboard[k][0]<<chessboard[k][1]<<chessboard[k][2]<<chessboard[k][3]<<chessboard[k][4]<<chessboard[k][5];
cout<<chessboard[k][6]<<chessboard[k][7]<<endl;}
}
}
}
return 0;
}
bool knighttour(square pt,int &counter,int cb[][8])
{
Marksquare(cb[pt.x][pt.y],counter);
if (counter==64)
return true;
counter++;
Vector <square> temp = generatemoves(pt);
for (int i=0;i<temp.size();i++)
{
if (IsLegal(temp[i],cb))
knighttour(temp[i],counter,cb);
}
Unmarksquare(cb[pt.x][pt.y]);
counter--;
return false;
}
Vector <square> generatemoves (square start)
{
Vector <square> temp;
Vector <square> temp2;
square mv1;
mv1.x=start.x+2;
mv1.y=start.y+1;
temp.add(mv1);
square mv2;
mv2.x=mv1.x;
mv2.y=start.y-1;
temp.add(mv2);
square mv3;
mv3.y=start.y+2;
mv3.x=start.x+1;
temp.add(mv3);
square mv4;
mv4.y=start.y+2;
mv4.x=start.x-1;
temp.add(mv4);
square mv5;
mv5.x=start.x-2;
mv5.y=start.y+1;
temp.add(mv5);
square mv6;
mv6.x=start.x-2;
mv6.y=start.y-1;
temp.add(mv6);
square mv7;
mv7.y=start.y-2;
mv7.x=start.x-1;
temp.add(mv7);
square mv8;
mv8.y=start.y-2;
mv8.x=start.x+1;
temp.add(mv8);
for (int i=0;i<temp.size();i++)
if (temp[i].x>=0 && temp[i].x<=7 && temp[i].y>=0 && temp[i].y<=7)
temp2.add(temp[i]);
return temp2;
}
void Marksquare(int &a,int ctr)
{
a=ctr;
}
void Unmarksquare(int &a)
{
a=-1;
}
bool IsLegal(square a,int cb[][8])
{
if (cb[a.x][a.y]==-1)
return true;
else
return false;
}
一点解释。我使用 int [8][8] 来表示国际象棋棋盘,最初我在棋盘的每个方格中放入数字 -1。
当骑士移动时,它用计数器(int counter)标记他访问的方格,并从那里(以及骑士可以采取的所有合法移动)进行递归调用以找到路径(目标是访问每个方格一次) )。
一旦计数器达到 64,函数 bool Knighttour(square start,int &counter,int cb[][8]) 必须返回 true,然后主程序应该显示“骑士之旅”,如 [8][8] 棋盘上标记的那样。
我相信我提供的上述代码在无限循环上运行。我让它运行 3 分钟。
Here's the code i wrote.
#include "genlib.h"
#include <iostream>
#include <math.h>
#include "vector.h"
struct square
{
int x;
int y;
};
bool knighttour(square start,int &counter,int cb[][8]);
Vector <square> generatemoves (square start);
void Marksquare(int &cb,int ctr);
void Unmarksquare(int &cb);
bool IsLegal(square a,int cb[][8]);
int main()
{
int chessboard[8][8];
for (int i=0;i<8;i++)
for (int j=0;j<8;j++)
chessboard[i][j]=-1;
int counter=1;
for (int i=0;i<8;i++){
for (int j=0;j<8;j++){
square temp;
temp.x=i;
temp.y=j;
if (knighttour(temp,counter,chessboard))
{
for (int k=0;k<8;k++){
cout<<chessboard[k][0]<<chessboard[k][1]<<chessboard[k][2]<<chessboard[k][3]<<chessboard[k][4]<<chessboard[k][5];
cout<<chessboard[k][6]<<chessboard[k][7]<<endl;}
}
}
}
return 0;
}
bool knighttour(square pt,int &counter,int cb[][8])
{
Marksquare(cb[pt.x][pt.y],counter);
if (counter==64)
return true;
counter++;
Vector <square> temp = generatemoves(pt);
for (int i=0;i<temp.size();i++)
{
if (IsLegal(temp[i],cb))
knighttour(temp[i],counter,cb);
}
Unmarksquare(cb[pt.x][pt.y]);
counter--;
return false;
}
Vector <square> generatemoves (square start)
{
Vector <square> temp;
Vector <square> temp2;
square mv1;
mv1.x=start.x+2;
mv1.y=start.y+1;
temp.add(mv1);
square mv2;
mv2.x=mv1.x;
mv2.y=start.y-1;
temp.add(mv2);
square mv3;
mv3.y=start.y+2;
mv3.x=start.x+1;
temp.add(mv3);
square mv4;
mv4.y=start.y+2;
mv4.x=start.x-1;
temp.add(mv4);
square mv5;
mv5.x=start.x-2;
mv5.y=start.y+1;
temp.add(mv5);
square mv6;
mv6.x=start.x-2;
mv6.y=start.y-1;
temp.add(mv6);
square mv7;
mv7.y=start.y-2;
mv7.x=start.x-1;
temp.add(mv7);
square mv8;
mv8.y=start.y-2;
mv8.x=start.x+1;
temp.add(mv8);
for (int i=0;i<temp.size();i++)
if (temp[i].x>=0 && temp[i].x<=7 && temp[i].y>=0 && temp[i].y<=7)
temp2.add(temp[i]);
return temp2;
}
void Marksquare(int &a,int ctr)
{
a=ctr;
}
void Unmarksquare(int &a)
{
a=-1;
}
bool IsLegal(square a,int cb[][8])
{
if (cb[a.x][a.y]==-1)
return true;
else
return false;
}
A little explanation. I am using an int [8][8] to represent the board of chess and initially i put in every square of the board the number -1.
As the Knight moves it marks the square that he visits with the counter (int counter) and from there (and for all the legal moves the knight can take) makes recursive calls to find a path (the goal is to visit each square exactly once).
Once the counter hits 64 the function bool knighttour(square start,int &counter,int cb[][8])
must return true and the main program then should display "the knight's tour" as it is marked on the [8][8] chessboard.
I believe that the above code i provided runs on an infinite loop. I let it run for 3 minutes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
理论说:
因此,为了确保您的程序正常运行,请尝试使用较小的电路板尺寸(例如 4x4)。
为了确保您的程序在合理的时间内运行 8x8,您必须更改算法。除了此处列出的之外,还有很多。
--编辑--
另外,为了确保您的程序正在执行某些操作,在开发过程中添加一些跟踪始终是一个好主意。
例如
Theory says:
So to ensure that your program works, try with smaller board size (say 4x4).
To ensure your program works for 8x8 in reasonable time you'll have to change the algorithm. There are many in addition to those listed here.
--edit--
also to ensure that your program is doing something, it's always a good idea to add some traces while you're still developing it.
E.g.
这段代码可能会尝试在骑士之旅中找到所有可能的路线,并将返回最后找到的路线。
而不是
尝试
This code probably tries to find all possible routes in knights tour and will return last found route.
Instead of
Try
我看到的一件事是,尽管在 Knighttour 中
counter==64
时返回 true,但它不会被传播,调用它的函数将返回 false.. 所以你在 main() 中永远不会注意到它。也就是说,即使你修复了算法,它也可能无法在你的一生中完成。
One thing I see is that although you
return true
whencounter==64
in knighttour, that doesn't get propagated, the function calling it will return false.. so you'll never notice it in main().That said, even if you fix your algorithm it might not finish in your lifetime.