0

I am trying to solve the problem where the problem states that, given a N * M chessboard, a Knight’s Tour is defined as the sequence of moves of a Knight, such that the Knight visits every square only once. Below is my code, however I am getting Array out of bound = 8, I know it comes when Moves tries to add value 2 in the present row with 6, however I am not sure how to get rid of it.

int MaxMove = 64; // for 8*8 chess Board
private int Moves[][] = new int[][] {{2, 1}, {2, -1}, {1, 2}, {1, -2}, {-2, 1}, {-2, -1}, {-1, 2}, {-1, -2}};

void solveKnightTour(int[][] board)
{
    knightsTourUtil(board, 0, 0, 1);
}

private boolean isSafeMove(int[][] board, int r, int c)
{
    if(r < 0 && r > board.length-1 && c < 0 && c > board.length-1 &&  board[r][c] != -1)
        return false;
    return true;
}

private boolean knightsTourUtil(int[][] board, int presentRow, int presentCol, int KthMove)
{
    if (KthMove >= MaxMove)
    {
        return true;
    }
    for (int i = 0; i < Moves.length; i++)
    {
        int nextRow = presentRow + Moves[i][0];
        int nextCol = presentCol + Moves[i][1];
        if (isSafeMove(board, nextRow, nextCol))
        {
            board[nextRow][nextCol] = KthMove;
            if (knightsTourUtil(board, nextRow, nextCol, KthMove + 1)) 
                return true;
            else
                board[nextRow][nextCol] = -1;
        }
    }
    return false;
}
AS Mackay
  • 2,463
  • 9
  • 15
  • 23

1 Answers1

1

You get that exception because you tryed to access element with index which is out of bounds for your array.

This happens because if statement inside isSafeMove method isn't doing what you want it to do.

if(r < 0 && r > board.length-1 && c < 0 && c > board.length-1 &&  board[r][c] != -1)

You used && so all those statements need to be true in other to execute if block, instead of && you should use || in other to make it work if only 1 of those cases is true.

Like this:

if(r < 0 || r > board.length-1 || c < 0 || c > board.length-1 ||  board[r][c] != -1)

EDIT At first I assumed that -1 is for not visited fields, but it turned out that -1 is for visited ones. If should look like this:

if(r < 0 || r > board.length-1 || c < 0 || c > board.length-1 ||  board[r][c] == -1)
FilipRistic
  • 2,261
  • 4
  • 20
  • 26
  • but in that case , if stamens returns false for is(safe, board, 2,1) when knight is at (0,0) even though it is a valid move. – lucifer_16 Jul 31 '18 at 03:35
  • Is -1 sign for already visited or not visited field? – FilipRistic Jul 31 '18 at 08:47
  • initially all indices of the board are zero, while backtracking or removing the knight we place -1 on that spot so that next time we visit we know this is place is not occupied.(I also tried making spot 0 again but that just results in an infinite loop) – lucifer_16 Jul 31 '18 at 11:40
  • just change last if case to `board[r][c] == -1` and it should work. – FilipRistic Jul 31 '18 at 13:26
  • Changed last statement to "==-1", now I am getting this output 00000000 00000000 01000000 00000000 002040620 00000000 000306300 00000000 – lucifer_16 Jul 31 '18 at 13:50
  • If you are placing `-1` when field is visited, and `0` is starting value, then that if case should work, you shouldn't reset spot to 0 again, leave it as -1, its impossible to get 2/3/4 or any other number unless you are putting it in array somewhere else. – FilipRistic Jul 31 '18 at 14:10