1

I've been trying to improve my recursion skills in C and I came across this question. I've tried to solve it, yet the code doesn't seem to work properly. For example, there are 108 options for the knight to move from (1,1) to (8,8) in 6 moves and in my code the result is completely different. The question asks how many ways are there to move a knight from (1,1) to (8,8) in n moves(n given from the user) in 8x8 board. here's my code:

#include <stdio.h>
#define SIZE 8
//x,y coordinates of the knight.
int knightsTour(int x, int y, int num);
void main() {
int n;
int result;
    do {
        scanf(" %d", &n);
        result = knightsTour(1,1,n);
        printf("%d\n", result);
    } while (n > 0);
}
int knightsTour(int x,int y,int num) {
int result = 0;
int i, j;
if (num == 0) {
    return 0;
}
if (((x > 8) || (y > 8))||((x == 8) && (y == 8))) {
    return 0;
}
for (i = 1; i <= SIZE; i++) {
    for (j = 1; j <= SIZE; j++) {
        if ((i != y) && (j != x) && ((i != y + j) && (j != x + i)) && ((i != y + j) && (j != x - i))
            && ((i != y - j) && (j != x + i)) && ((i != y - j) && (j != x - i))) {
            result += knightsTour(i, j, num - 1) + 1;
        }
    }
}
return result;
}
Cbeginner
  • 59
  • 1
  • 7

1 Answers1

1

Your code has several problems:

  • You add one to the results unconditionally when you call your recursivev function. You should only count paths that land on h8 after 6 moves, for which you can check only after you have jumped to the new position.
  • When you want to find possible moves, it is wasteful to check all squares on the board. You know the rank and file of the knight, so you also know the eight possible moves. You must take care not to jump off the board. It is easier to verify that rank and file are valid at the beginning of the function.

One approach would be the following recursive method:

  • Are rank and file valid? If not, return 0.
  • Have we reached the desired number of moves? If so, return 1 if the current square is h8, and 0 otherwise.
  • Return the sum of the number of valid moves the knight can make with one fewer move for the eight possible moves from the current positions. You don't need to check here, because the validity of a move will be checked at the beginning of the function.

Putting this together:

#include <stdio.h>

#define SIZE 8

int knightsTour(int x, int y, int num)
{
    if (x < 1 || x > SIZE) return 0;
    if (y < 1 || y > SIZE) return 0;

    if (num == 0) return (x == SIZE && y == SIZE);

    return knightsTour(x + 2, y + 1, num - 1)
         + knightsTour(x + 1, y + 2, num - 1)
         + knightsTour(x - 1, y + 2, num - 1)
         + knightsTour(x - 2, y + 1, num - 1)
         + knightsTour(x - 2, y - 1, num - 1)
         + knightsTour(x - 1, y - 2, num - 1)
         + knightsTour(x + 1, y - 2, num - 1)
         + knightsTour(x + 2, y - 1, num - 1);
}

int main(void)
{
    int result = knightsTour(1, 1, 6);

    printf("%d\n", result);
    return 0;
}

This code is straightforward and it determines the 108 possible moves.

M Oehm
  • 28,726
  • 3
  • 31
  • 42
  • first of all, thank you for your help! seconed of all, I didn't quite understand what you did here: return knightsTour(x + 2, y + 1, num - 1) + knightsTour(x + 1, y + 2, num - 1) + knightsTour(x - 1, y + 2, num - 1) + knightsTour(x - 2, y + 1, num - 1) + knightsTour(x - 2, y - 1, num - 1) + knightsTour(x - 1, y - 2, num - 1) + knightsTour(x + 1, y - 2, num - 1) + knightsTour(x + 2, y - 1, num - 1); – Cbeginner Sep 17 '17 at 18:12
  • Is that a curtain algorithem to solve the knight's tour? – Cbeginner Sep 17 '17 at 18:15
  • From its current position, the knight can make one of eight moves, see [here](https://en.wikipedia.org/wiki/Knight_(chess)) in the picture that marks the possible moves of the black knight with dots. Some of them may take the knight off the board. I just have hardcoded the recursive call for these eight positions. If the knight jumps off the board, the called function returns 0 immediately. – M Oehm Sep 17 '17 at 18:18
  • @Cbeginner: It's the same algorithm you wanted to implement, but with corrected checks and return values. – M Oehm Sep 17 '17 at 18:26
  • I'm kinda mad at myself for the "nonsense" I wrote. After your explanation I see how smart the solution is! Thank you for correcting the code and explaining it! I learned from you and I hope to solve questions like this better. I'm gonna try to solve other questions about this topic to improve even more, thank you! – Cbeginner Sep 17 '17 at 18:35
  • I'm glad that the answer was useful. Don't be mad at yourself. All of us write nonsense occasionally and feel silly afterwards. – M Oehm Sep 17 '17 at 18:48
  • 1
    @chux: Oops, that should be an ´int`, of course. (The `float` was in the first draft in the OP, and I've stupidly copied it. Assigning it to an `int`has masked the error.) – M Oehm Sep 18 '17 at 07:49