鱼C论坛

 找回密码
 立即注册
查看: 1740|回复: 4

自己试着写了一下马踏棋盘,看了好几个小时了。真的看不出问题

[复制链接]
发表于 2023-2-20 23:14:54 | 显示全部楼层 |阅读模式
50鱼币
这个是我的代码
#include <stdio.h>
#include <time.h>

#define X 8
#define Y 8

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

void print() {
    int i, j;
    for (i = 0; i < X; i++) {
        for (j = 0; j < Y; j++) {
            printf("%2d  ", chess[i][j]);
        }
        putchar('\n');
    }
}

//根据xy坐标,判断指定位置可不可走,如果可走改变传入的x y坐标
int decide_next(int* px, int* py, int count) {
    int x = *px, y = *py;

    switch (count) {
    case 0:
        if (x + 2 < X && y - 1 >= 0 && chess[x + 2][y - 1] == 0) {
            *px = x + 2;
            *py = y - 1;
            return 1;
        }
        break;
    case 1:
        if (x + 2 < X && y + 1 < Y && chess[x + 2][y + 1] == 0) {
            *px = x + 2;
            *py = y + 1;
            return 1;
        }
        break;
    case 2:
        if (x + 1 < X && y - 2 >= 0 && chess[x + 1][y - 2] == 0) {
            *px = x + 1;
            *py = y - 2;
            return 1;
        }
        break;
    case 3:
        if (x + 1 < X && y + 2 < Y && chess[x + 1][y + 2] == 0) {
            *px = x + 1;
            *py = y + 2;
            return 1;
        }
        break;
    case 4:
        if (x - 2 >= 0 && y - 1 >= 0 && chess[x - 2][y - 1] == 0) {
            *px = x - 2;
            *py = y - 1;
            return 1;
        }
        break;
    case 5:
        if (x - 2 >= 0 && y + 1 < Y && chess[x - 2][y + 1] == 0) {
            *px = x - 2;
            *py = y + 1;
            return 1;
        }
        break;
    case 6:
        if (x - 1 >= 0 && y - 2 >= 0 && chess[x - 1][y - 2] == 0) {
            *px = x - 1;
            *py = y - 2;
            return 1;
        }
        break;
    case 7:
        if (x - 1 >= 0 && y + 2 < Y && chess[x - 1][y + 2] == 0) {
            *px = x - 1;
            *py = y + 2;
            return 1;
        }
        break;
    default:
        break;
    }
    return 0;
}
// 获得棋子的路径
int setHorse(int x, int y, int tag){
    int x1, y1, resule = 0, count = 0;

    // tag记录轨迹
    chess[x][y] = tag;
    if (tag == 62) {
        tag = 62;
    }
    // 如果tag等于64打印棋盘
    if (tag == X * Y) {
        return 1;
    }

    // 递归进入下一个坐标
    while (count < 8){
        
        // 尝试路径是否能走
        resule = decide_next(&x1, &y1, count);
        if (!resule) {
            count += 1;
        }
        for (x1 = x, y1 = y; resule == 0 && count < 8; count += 1) {
            resule = decide_next(&x1, &y1, count);
        }
        // 返回1表示成功找到路径;对新的点进行尝试
        if (setHorse(x1, y1, tag + 1))
        {
            return 1;
        }
        // 如果失败并且有没尝试的路径,回到上一步重新尝试
        count += 1;
    }
    // 如果全部路径都尝试过,并且没有返回1,说明这个点没有可行的路径,回到上一步并且去除痕迹
    chess[x][y] = 0;

    return 0;
}

int main(void){
    int i, j, x, y;
    clock_t start, finish;

    for (i = 0; i < X; i++) {
        for (j = 0; j < Y; j++){
            chess[i][j] = 0;
        }
    }

    // 获取初始坐标;建议(2,0)
    printf("请输入初始坐标(x y):");
    scanf_s("%d %d", &x, &y);

    // 记录开始时间
    start = clock();

    if (setHorse(x, y, 1)) {
        print();
    }
    else{
        printf("可惜无解!\n");
    }

    // 记录结束时间
    finish = clock();

    printf("\n本次计算一共耗时∶%f秒\n", (double)(finish - start) / CLOCKS_PER_SEC);

    return 0;
}

这一段代码
// 获得棋子的路径
int setHorse(int x, int y, int tag){
    int x1, y1, resule = 0, count = 0;

    // tag记录轨迹
    chess[x][y] = tag;
    if (tag == 62) {
        tag = 62;
    }
    // 如果tag等于64打印棋盘
    if (tag == X * Y) {
        return 1;
    }

    // 递归进入下一个坐标
    while (count < 8){
        
        // 尝试路径是否能走
        resule = decide_next(&x1, &y1, count);
        if (!resule) {
            count += 1;
        }
        for (x1 = x, y1 = y; resule == 0 && count < 8; count += 1) {
            resule = decide_next(&x1, &y1, count);
        }
        // 返回1表示成功找到路径;对新的点进行尝试
        if (setHorse(x1, y1, tag + 1))
        {
            return 1;
        }
        // 如果失败并且有没尝试的路径,回到上一步重新尝试
        count += 1;
    }
    // 如果全部路径都尝试过,并且没有返回1,说明这个点没有可行的路径,回到上一步并且去除痕迹
    chess[x][y] = 0;

    return 0;
}
改成
nt setHorse(int x, int y, int tag)
{
        int x1 = x, y1 = y, flag = 0, count = 0;

        // tag记录轨迹
        chess[x][y] = tag;
        // 如果tag等于64退出程序
        if (tag == X*Y)
        {
                return 1;
        }

        // 如果可以走,那么flag为1
        flag = next(&x1, &y1, count);
        // 否则尝试其他路径
        while (flag == 0 && count < 7)
        {
                count += 1;
                flag = next(&x1, &y1, count);
        }

        // 递归进入下一个坐标
        while (flag)
        {
                // 返回1表示成功找到落脚点
                if (setHorse(x1, y1, tag+1))
                {
                        return 1;
                }
                // 否则从上一步重新尝试
                x1 = x;
                y1 = y;
                count += 1;
                flag = next(&x1, &y1, count);
                while (flag == 0 && count < 7)
                {
                        count += 1;
                        flag = next(&x1, &y1, count);
                }
        }

        if (flag == 0)
        {
                chess[x][y] = 0;
        }

        return 0;
}
就可以。不知道问题在哪里。想知道是哪里错误了?

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-21 21:14:06 | 显示全部楼层
sh-5.1$ cat main.c
#include <stdio.h>
#include <time.h>

#define X 8
#define Y 8

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

void print(void) {
    int i, j;
    for(i = 0; i < X; i++) {
        for(j = 0; j < Y; j++) {
            printf("%2d  ", chess[i][j]);
        }
        putchar('\n');
    }
}

// 根据xy坐标,判断指定位置可不可走,如果可走改变传入的x y坐标
int decide_next(int *px, int *py, int count) {
    int x = *px, y = *py;

    switch(count) {
    case 0:
        if(x + 2 < X && y - 1 >= 0 && chess[x + 2][y - 1] == 0) {
            *px = x + 2;
            *py = y - 1;
            return 1;
        }
        break;
    case 1:
        if(x + 2 < X && y + 1 < Y && chess[x + 2][y + 1] == 0) {
            *px = x + 2;
            *py = y + 1;
            return 1;
        }
        break;
    case 2:
        if(x + 1 < X && y - 2 >= 0 && chess[x + 1][y - 2] == 0) {
            *px = x + 1;
            *py = y - 2;
            return 1;
        }
        break;
    case 3:
        if(x + 1 < X && y + 2 < Y && chess[x + 1][y + 2] == 0) {
            *px = x + 1;
            *py = y + 2;
            return 1;
        }
        break;
    case 4:
        if(x - 2 >= 0 && y - 1 >= 0 && chess[x - 2][y - 1] == 0) {
            *px = x - 2;
            *py = y - 1;
            return 1;
        }
        break;
    case 5:
        if(x - 2 >= 0 && y + 1 < Y && chess[x - 2][y + 1] == 0) {
            *px = x - 2;
            *py = y + 1;
            return 1;
        }
        break;
    case 6:
        if(x - 1 >= 0 && y - 2 >= 0 && chess[x - 1][y - 2] == 0) {
            *px = x - 1;
            *py = y - 2;
            return 1;
        }
        break;
    case 7:
        if(x - 1 >= 0 && y + 2 < Y && chess[x - 1][y + 2] == 0) {
            *px = x - 1;
            *py = y + 2;
            return 1;
        }
        break;
    }
    return 0;
}

// 获得棋子的路径
int setHorse(int x, int y, int tag) {
    //int x1, y1, resule = 0, count = 0;
    int x1, y1, count = 0;

    // tag记录轨迹
    chess[x][y] = tag;


#if 0
    // ???
    // 这是在做什么?
    if(tag == 62) {
        tag = 62;
    }
#endif


    // 如果tag等于64打印棋盘
    if(tag == X * Y) {
        return 1;
    }

    // 递归进入下一个坐标
    while(count < 8) {

        // 尝试路径是否能走
        x1 = x; y1 = y;
        //if(!decide_next(&x1, &y1, count)) {++count; continue;}
        /*
        resule = decide_next(&x1, &y1, count);
        if(!resule) {
            count += 1;
        }
        */
        /*
        // 这个for循环是在做什么?
        // 这里需要两层循环吗?
        for(x1 = x, y1 = y; resule == 0 && count < 8; count += 1) {
            resule = decide_next(&x1, &y1, count);
        }
        */
        // 返回1表示成功找到路径;对新的点进行尝试
        if(decide_next(&x1, &y1, count)) {
            if(setHorse(x1, y1, tag + 1)) return 1;
        }
        // 如果失败并且有没尝试的路径,回到上一步重新尝试
        count += 1;
    }
    // 如果全部路径都尝试过,并且没有返回1,说明这个点没有可行的路径,回到上一步并且去除痕迹
    chess[x][y] = 0;

    return 0;
}

int main(void) {
    int i, j, x, y;
    clock_t start, finish;

    for(i = 0; i < X; i++) {
        for(j = 0; j < Y; j++) {
            chess[i][j] = 0;
        }
    }

    // 获取初始坐标;建议(2,0)
    printf("请输入初始坐标(x y):");
    //scanf_s("%d %d", &x, &y);
    scanf("%d%d", &x, &y);

    // 记录开始时间
    start = clock();

    if(setHorse(x, y, 1)) {
        print();
    } else {
        printf("可惜无解!\n");
    }

    // 记录结束时间
    finish = clock();

    printf("\n本次计算一共耗时∶%f秒\n", (double)(finish - start) / CLOCKS_PER_SEC);

    return 0;
}
sh-5.1$ ./main
请输入初始坐标(x y):1 1
53  48  51  38  55  40  61  36
50   1  54  47  60  37  56  41
11  52  49  44  39  58  35  62
 2  19  12  59  46  33  42  57
13  10  45  20  43  28  63  34
18   3  16   7  26  23  32  29
 9  14   5  24  21  30  27  64
 4  17   8  15   6  25  22  31

本次计算一共耗时∶1.926012秒
sh-5.1$
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-21 22:00:29 | 显示全部楼层

然而他的意图是debug而不是做题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-21 22:36:44 | 显示全部楼层
原先的代码栈溢出挂掉了。
问题还在看。
先指出几点明确的:
count有高亮,不要乱用作标识符
中间有一个意义不明的“如果tag==62就把tag=62”,人家都等于62了,就不用赋值成62了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-2-22 20:49:28 | 显示全部楼层
ExiaGN001 发表于 2023-2-21 22:36
原先的代码栈溢出挂掉了。
问题还在看。
先指出几点明确的:

那个tag是设置断点的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-17 19:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表