I am trying to solve a similar problem to the Knight-Tour-Problem. The problem:
A knight is placed on the upper-left square of a chess board. You are given a vector of numbers(the numbers represent the squares of the chess board, as numbered from left to right, from 1 to 64). The knight has to get to those squares in the vector, one after the other, and at the end you should output the path the knight took. Note that the knight might visit a square more than once.
I tried solving this problem similar to the Knight-Tour Problem, using backtracking. However I got stuck at the "visit a square more than once". If I don´t put any condition, the knight just jumps back and forth between 2 squares and never gets anywhere. I also tried somehow restricting the knight from returning to the square it came before, but then I got a larger loop. Is there something I am missing or is backtracking in general wrong in this particular case?
Below is my code. Note that I used only the lower-right square as the target for the knight to reach it, as a simple test and even then the program failed and debugger showed me the knight was still walking in endless loops.
#include <iostream>
#include <cmath>
using namespace std;
const int n = 8;
bool found = 0;
int *path = new int[n*n];
int pathindex=0;
bool visited[n][n];
void print(int (*matrica)[n]); //function to print a matrix
void printpath(int path[n*n]){
for(int i=0;i<pathindex;i++)
cout<<path[i]<<" ";
cout<<endl;
}
void knight(int (*matrica)[n], int x, int y, int path[n*n], int &pathindex){
if(found){
return;
}
if (x==7 && y == 7){ //if knight landed on the target, output the result
found = 1;
path[pathindex]=matrica[7][7];
pathindex++;
printpath(path);
return;
}
if(x > n-1 || y > n-1 || x < 0 || y < 0){ //if coordinates out of bounds, dismiss
return;
}
path[pathindex]= matrica[x][y];
pathindex++;
//all possible knight moves
if(path[pathindex-1]!=matrica[x-1][y+2]) //conditions to test if the next square was the one we came from
knight(matrica, x-1, y+2, path, pathindex);
if(path[pathindex-1]!=matrica[x-2][y+1])
knight(matrica, x-2, y+1, path, pathindex);
if(path[pathindex-1]!=matrica[x+1][y+2])
knight(matrica, x+1, y+2, path, pathindex);
if(path[pathindex-1]!=matrica[x+2][y+1])
knight(matrica, x+2, y+1, path, pathindex);
if(path[pathindex-1]!=matrica[x+2][y-1])
knight(matrica, x+2, y-1, path, pathindex);
if(path[pathindex-1]!=matrica[x+1][y-2])
knight(matrica, x+1, y-2, path, pathindex);
if(path[pathindex-1]!=matrica[x-1][y-2])
knight(matrica, x-1, y-2, path, pathindex);
if(path[pathindex-1]!=matrica[x-2][y-1])
knight(matrica, x-2, y-1, path, pathindex);
pathindex--;
}
int main(){
int matrica[n][n];
int k = 1;
for(int i=0;i<n;i++){ //number the chess board
for(int j=0;j<n;j++){
matrica[i][j] = k;
k++;}
}
print(matrica);
knight(matrica, 0, 0, path, pathindex);
if(!found)
cout<<"No Solution!";
return 0;
}
void print(int (*matrica)[n]){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(matrica[i][j]<10)
cout<<" "<<matrica[i][j]<<" ";
else
cout<<matrica[i][j]<<" ";
}
cout<<endl;
}
cout<<endl<<endl;
}
How can I implement the part where the knight can use the same square more than once, yet it cannot walk on loops where it was?
Please note that this is no homework or school related project whatsoever, It´s just for my own personal fun.