0

So, in short I'm working on a knight's tour program. If you don't know what that is, the knight gets put on the chess board and you have to move it to every spot on the board exactly once. I'm using a recursive function but am having trouble getting my backtracking to work. I can get to 22 steps in a 5x5 board but the program won't back up and try a different path. I'm posting just the recursive part of my code (sorry it's a little long) Any insight would be extremely helpful. Thanks a lot!

`bool findPath ( int board[][boardSize + 4], int &currRow, int &currCol, int &currMove,int boardSize )
{
    int i, j;
    bool foundSpot;

    board[currRow][currCol] = currMove;

    if ( currMove == boardSize * boardSize )
        return true;

    for ( i = 0; i < boardSize + 4; i++ )
    {
        for ( j = 0; j < boardSize + 4; j++ )
            cout << setw (3) << board[i][j];
        cout<<endl;
    }
    cout << endl;

    if ( board[currRow - 2][currCol - 1] == 0 )
    {
        currMove += 1;
        board[currRow - 2][currCol - 1] = currMove;
        currRow -= 2;
        currCol -= 1;
        if ( findPath( board, currRow, currCol, currMove, boardSize ) )
            return true;
    }

    if ( board[currRow - 2][currCol + 1] == 0 )
    {
        currMove += 1;
        board[currRow - 2][currCol + 1] = currMove ;
        currRow -= 2;
        currCol += 1;
        if ( findPath( board, currRow, currCol, currMove, boardSize ) )
            return true;
    }

    if ( board[currRow - 1][currCol + 2] == 0 )
    {
        currMove += 1;
        board[currRow - 1][currCol + 2] = currMove ;
        currRow -= 1;
        currCol += 2;
        if ( findPath( board, currRow, currCol, currMove, boardSize ) )
            return true;
    }

    if ( board[currRow + 1][currCol + 2] == 0 )
    {       
        currMove += 1;
        board[currRow + 1][currCol + 2] = currMove ;
        currRow += 1;
        currCol += 2;
        if ( findPath( board, currRow, currCol, currMove, boardSize ) )
            return true;
    }

    if ( board[currRow + 2][currCol + 1] == 0 )
    {
        currMove += 1;
        board[currRow + 2][currCol + 1] = currMove ;
        currRow += 2;
        currCol += 1;
        if ( findPath( board, currRow, currCol, currMove, boardSize ) )
            return true;
    }

    if ( board[currRow + 2][currCol - 1] == 0 )
    {
        currMove += 1;
        board[currRow + 2][currCol - 1] = currMove ;
        currRow += 2;
        currCol -= 1;
        if ( findPath( board, currRow, currCol, currMove, boardSize ) )
            return true;
    }

    if ( board[currRow + 1][currCol - 2] == 0 )
    {       
        currMove += 1;
        board[currRow + 1][currCol - 2] = currMove ;
        currRow += 1;
        currCol -= 2;
        if ( findPath( board, currRow, currCol, currMove, boardSize ) )
            return true;
    }

    if ( board[currRow - 1][currCol - 2] == 0 )
    {       
        currMove += 1;
        board[currRow - 1][currCol - 2] = currMove ;        
        currRow -= 1;
        currCol -= 2;
        if ( findPath( board, currRow, currCol, currMove, boardSize ) )
            return true;
    }
    board[currRow][currCol] = 0;
    currMove -= 2;
    return false;
}`
false
  • 10,264
  • 13
  • 101
  • 209
  • Welcome to Stack Overflow! Asking people to spot errors in your code is not especially productive. You should use the debugger (or add print statements) to isolate the problem, by tracing the progress of your program, and comparing it to what you expect to happen. As soon as the two diverge, then you've found your problem. (And then if necessary, you should construct a [minimal test-case](http://sscce.org).) – Oliver Charlesworth Apr 09 '13 at 00:12
  • I don't think changing currRow and currCol in each recursion block is a good idea - it means the next recursion block will start from the wrong square, and your `board[currRow][currCol] = 0;` will clear the last recursion and not your step at this level (set at the very top). Why are you setting board and changing the row and column variables in each `if` at all? Shouldn't the recursed call take care of that? And I don't think you want your row, col, move inputs to be references - pass by value instead! – Rup Apr 09 '13 at 00:16
  • And you'll also want to range-check every `if (board[][] == 0)` test to make sure both coordinates are in-bounds. And to save repeating yourself, you might want to build an array of the move permutations and loop through them. – Rup Apr 09 '13 at 00:21

1 Answers1

0

I worked out the following implementation of the Knights tour in c++ :

#include<cstdio>
#include<iostream>
#define MAX 10

using namespace std;
int tour=1;
int board[MAX][MAX];

bool is_travelled(int,int);
bool knights_tour(int,int,int,int);
void initialize(int);
void display(int);

int main(int argc,char** argv){
    int n;
    scanf("%d",&n);
    for(int i=0;i<10;i++){
        for(int j=0;j<10;j++){
            board[i][j]=-1;
        }
    }
    initialize(n);
    display(n);
    return 0;
}

bool is_travelled(int x,int y){
    if(x<0 || y<0)return true;
    if(board[x][y]==-1)return false;
    return true;
}

bool knights_tour(int i,int j,int n,int k){ // k=number of places remained , n=side of chess_board;
    int x,y;
    if(k==0)return true;
    // hard-coded cases;
    // reordering of the cases have significant effect on the execution time
    x=i+2;y=j+1;
    if((!is_travelled(x,y))&&x<n&&y<n){
        board[x][y]=tour;
        tour+=1;
        if(knights_tour(x,y,n,k-1))return true;
        board[x][y]=-1;
        tour-=1;
    }
    x=i+1;y=j+2;
    if((!is_travelled(x,y))&&x<n&&y<n){
        board[x][y]=tour;
        tour+=1;
        if(knights_tour(x,y,n,k-1))return true;
        board[x][y]=-1;
        tour-=1;
    }
    x=i-1;y=j+2;
    if((!is_travelled(x,y))&&x<n&&y<n){
        board[x][y]=tour;
        tour+=1;
        if(knights_tour(x,y,n,k-1))return true;
        board[x][y]=-1;
        tour-=1;
    }
    x=i-2;y=j+1;
    if((!is_travelled(x,y))&&x<n&&y<n){
        board[x][y]=tour;
        tour+=1;
        if(knights_tour(x,y,n,k-1))return true;
        board[x][y]=-1;
        tour-=1;
    }
    x=i-2;y=j-1;
    if((!is_travelled(x,y))&&x<n&&y<n){
        board[x][y]=tour;
        tour+=1;
        if(knights_tour(x,y,n,k-1))return true;
        board[x][y]=-1;
        tour-=1;
    }
    x=i-1;y=j-2;
    if((!is_travelled(x,y))&&x<n&&y<n){
        board[x][y]=tour;
        tour+=1;
        if(knights_tour(x,y,n,k-1))return true;
        board[x][y]=-1;
        tour-=1;
    }
    x=i+1;y=j-2;
    if((!is_travelled(x,y))&&x+y<n&&x<n&&y<n){
        board[x][y]=tour;
        tour+=1;
        if(knights_tour(x,y,n,k-1))return true;
        board[x][y]=-1;
        tour-=1;
    }
    x=i+2;y=j-1;
    if((!is_travelled(x,y))&&x<n&&y<n){
        board[x][y]=tour;
        tour+=1;
        if(knights_tour(x,y,n,k-1))return true;
        board[x][y]=-1;
        tour-=1;
    }
    return false;
}
void initialize(int n){
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            board[i][j]=0;
            int r=knights_tour(i,j,n,n*n-1);
            if(r==1)return;
            board[i][j]=-1;
        }
    }
}

void display(int n){
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            printf("%2d ",board[i][j]);
        }
        printf("\n");
    }
    cout<<endl;
}

Hope this helps . Happy Coding !

Anmol Gautam
  • 949
  • 1
  • 12
  • 27