马踏棋盘C语言简单版本实现(内有详细注释)

#include 
#include 

#define X 5 // 棋盘宽
#define Y 5 // 棋盘高

int chess[X][Y]; // 棋盘

// 打印棋盘
void printChess()
{
     
    int i, j;
    printf("This is horse Chess:\n");
    for (i = 0; i < X; i++)
    {
     
        for (j = 0; j < Y; j++)
        {
     
            printf("%2d\t", chess[i][j]);
        }
        printf("\n");
    }
}

// 马的8种走法,走下一步棋,改变(x,y)的值, step为方向
int next(int *x, int *y, int step)
{
     
    // 马的8种走法
    switch (step)
    {
     
    case 0:
    //               走的范围不能超过棋盘               下一步为没走过的
        if (*y + 2 <= Y - 1 && *x - 1 >= 0 && chess[*x - 1][*y + 2] == 0)
        {
     
            // 走一步棋
            *y += 2;
            *x -= 1;
            // 走成功了,返回1
            return 1;
        }
        break;
    case 1:
        if (*y + 2 <= Y - 1 && *x + 1 <= X - 1 && chess[*x + 1][*y + 2] == 0)
        {
     
            *y += 2;
            *x += 1;
            return 1;
        }
        break;
    case 2:
        if (*y + 1 <= Y - 1 && *x + 2 <= X - 1 && chess[*x + 2][*y + 1] == 0)
        {
     
            *y += 1;
            *x += 2;
            return 1;
        }
        break;
    case 3:
        if (*y - 1 >= 0 && *x + 2 <= X - 1 && chess[*x + 2][*y - 1] == 0)
        {
     
            *y -= 1;
            *x += 2;
            return 1;
        }
        break;
    case 4:
        if (*y - 2 >= 0 && *x + 1 <= X - 1 && chess[*x + 1][*y - 2] == 0)
        {
     
            *y -= 2;
            *x += 1;
            return 1;
        }
        break;
    case 5:
        if (*y - 2 >= 0 && *x - 1 >= 0 && chess[*x - 1][*y - 2] == 0)
        {
     
            *y -= 2;
            *x -= 1;
            return 1;
        }
        break;
    case 6:
        if (*y - 1 >= 0 && *x - 2 >= 0 && chess[*x - 2][*y - 1] == 0)
        {
     
            *y -= 1;
            *x -= 2;
            return 1;
        }
        break;
    case 7:
        if (*y + 1 <= Y - 1 && *x - 2 >= 0 && chess[*x - 2][*y + 1] == 0)
        {
     
            *y += 1;
            *x -= 2;
            return 1;
        }
        break;
    default:
        break;
    }
    // 8种走法都不行,返回0
    return 0;
}

// 核心函数!!!!
// 递归的函数!!!!
// 最难的函数!!!!
int horse(int x, int y, int tag)
{
     
    int x_t = x, y_t = y;    // 接管x,y
    // flag为next函数的返回值,走棋是否成功。
    // count为走棋次数,用于判断是否大于7(8种走法都不行),同时用于后续的此路不通走下一条路
    int flag = 0, count = 0;   
    chess[x][y] = tag;    // 第几步

    // 遍历完成,跳出函数返回1
    if (tag == X * Y)
    {
     
        printChess();
        return 1;
    }

    flag = next(&x_t, &y_t, count);
    // 8种情况先过一遍,跳出情况为返回出了走法或者8次机会用完
    while (!flag && count <= 7)
    {
     
        count++;
        flag = next(&x_t, &y_t, count);
    }
    // 进入情况为flag正常,可以走下一步,跳出情况为8次机会用完后还是无路可走,回溯
    while (flag)
    {
     
        // 开始递归,步数+1(这里不是全局的tag+1,只是递归中的tag+1),
        if (horse(x_t, y_t, tag + 1))
            return 1;
        // 递归暴毙,开始回溯,获取当前(x,y),当前的count++的意思就是此处走过的错误的路不走了,走下一个路
        x_t = x, y_t = y, count++;
        flag = next(&x_t, &y_t, count);
        // 再给一次机会,走,走得通就继续while循环继续递归,走不通再回溯
        while (!flag && count <= 7)
        {
     
            count++;
            flag = next(&x_t, &y_t, count);
        }
    }
    // 回溯的同时这条路标记为0(没走过)
    if (!flag)
        chess[x][y] = 0;
    return 0;
}

int main()
{
     
    int i, j;
    // 初始化棋盘
    for (i = 0; i < X; i++)
    {
     
        for (j = 0; j < Y; j++)
        {
     
            chess[i][j] = 0;
        }
    }

    clock_t begin, end;
    begin = clock();
    if (!horse(2, 0, 1))
    {
     
        printf("The horse Chess is unavailable!");
    }
    end = clock();
    printf("This time used is %0.2lf\n", (double)(end - begin) / CLOCKS_PER_SEC);
    return 0;
}

你可能感兴趣的:(算法,c语言)