鱼C论坛

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

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

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

  3. #define X 8
  4. #define Y 8

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

  6. void print() {
  7.     int i, j;
  8.     for (i = 0; i < X; i++) {
  9.         for (j = 0; j < Y; j++) {
  10.             printf("%2d  ", chess[i][j]);
  11.         }
  12.         putchar('\n');
  13.     }
  14. }

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

  18.     switch (count) {
  19.     case 0:
  20.         if (x + 2 < X && y - 1 >= 0 && chess[x + 2][y - 1] == 0) {
  21.             *px = x + 2;
  22.             *py = y - 1;
  23.             return 1;
  24.         }
  25.         break;
  26.     case 1:
  27.         if (x + 2 < X && y + 1 < Y && chess[x + 2][y + 1] == 0) {
  28.             *px = x + 2;
  29.             *py = y + 1;
  30.             return 1;
  31.         }
  32.         break;
  33.     case 2:
  34.         if (x + 1 < X && y - 2 >= 0 && chess[x + 1][y - 2] == 0) {
  35.             *px = x + 1;
  36.             *py = y - 2;
  37.             return 1;
  38.         }
  39.         break;
  40.     case 3:
  41.         if (x + 1 < X && y + 2 < Y && chess[x + 1][y + 2] == 0) {
  42.             *px = x + 1;
  43.             *py = y + 2;
  44.             return 1;
  45.         }
  46.         break;
  47.     case 4:
  48.         if (x - 2 >= 0 && y - 1 >= 0 && chess[x - 2][y - 1] == 0) {
  49.             *px = x - 2;
  50.             *py = y - 1;
  51.             return 1;
  52.         }
  53.         break;
  54.     case 5:
  55.         if (x - 2 >= 0 && y + 1 < Y && chess[x - 2][y + 1] == 0) {
  56.             *px = x - 2;
  57.             *py = y + 1;
  58.             return 1;
  59.         }
  60.         break;
  61.     case 6:
  62.         if (x - 1 >= 0 && y - 2 >= 0 && chess[x - 1][y - 2] == 0) {
  63.             *px = x - 1;
  64.             *py = y - 2;
  65.             return 1;
  66.         }
  67.         break;
  68.     case 7:
  69.         if (x - 1 >= 0 && y + 2 < Y && chess[x - 1][y + 2] == 0) {
  70.             *px = x - 1;
  71.             *py = y + 2;
  72.             return 1;
  73.         }
  74.         break;
  75.     default:
  76.         break;
  77.     }
  78.     return 0;
  79. }
  80. // 获得棋子的路径
  81. int setHorse(int x, int y, int tag){
  82.     int x1, y1, resule = 0, count = 0;

  83.     // tag记录轨迹
  84.     chess[x][y] = tag;
  85.     if (tag == 62) {
  86.         tag = 62;
  87.     }
  88.     // 如果tag等于64打印棋盘
  89.     if (tag == X * Y) {
  90.         return 1;
  91.     }

  92.     // 递归进入下一个坐标
  93.     while (count < 8){
  94.         
  95.         // 尝试路径是否能走
  96.         resule = decide_next(&x1, &y1, count);
  97.         if (!resule) {
  98.             count += 1;
  99.         }
  100.         for (x1 = x, y1 = y; resule == 0 && count < 8; count += 1) {
  101.             resule = decide_next(&x1, &y1, count);
  102.         }
  103.         // 返回1表示成功找到路径;对新的点进行尝试
  104.         if (setHorse(x1, y1, tag + 1))
  105.         {
  106.             return 1;
  107.         }
  108.         // 如果失败并且有没尝试的路径,回到上一步重新尝试
  109.         count += 1;
  110.     }
  111.     // 如果全部路径都尝试过,并且没有返回1,说明这个点没有可行的路径,回到上一步并且去除痕迹
  112.     chess[x][y] = 0;

  113.     return 0;
  114. }

  115. int main(void){
  116.     int i, j, x, y;
  117.     clock_t start, finish;

  118.     for (i = 0; i < X; i++) {
  119.         for (j = 0; j < Y; j++){
  120.             chess[i][j] = 0;
  121.         }
  122.     }

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

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

  128.     if (setHorse(x, y, 1)) {
  129.         print();
  130.     }
  131.     else{
  132.         printf("可惜无解!\n");
  133.     }

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

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

  137.     return 0;
  138. }
复制代码


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

  4.     // tag记录轨迹
  5.     chess[x][y] = tag;
  6.     if (tag == 62) {
  7.         tag = 62;
  8.     }
  9.     // 如果tag等于64打印棋盘
  10.     if (tag == X * Y) {
  11.         return 1;
  12.     }

  13.     // 递归进入下一个坐标
  14.     while (count < 8){
  15.         
  16.         // 尝试路径是否能走
  17.         resule = decide_next(&x1, &y1, count);
  18.         if (!resule) {
  19.             count += 1;
  20.         }
  21.         for (x1 = x, y1 = y; resule == 0 && count < 8; count += 1) {
  22.             resule = decide_next(&x1, &y1, count);
  23.         }
  24.         // 返回1表示成功找到路径;对新的点进行尝试
  25.         if (setHorse(x1, y1, tag + 1))
  26.         {
  27.             return 1;
  28.         }
  29.         // 如果失败并且有没尝试的路径,回到上一步重新尝试
  30.         count += 1;
  31.     }
  32.     // 如果全部路径都尝试过,并且没有返回1,说明这个点没有可行的路径,回到上一步并且去除痕迹
  33.     chess[x][y] = 0;

  34.     return 0;
  35. }
复制代码

改成
  1. nt setHorse(int x, int y, int tag)
  2. {
  3.         int x1 = x, y1 = y, flag = 0, count = 0;

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

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

  19.         // 递归进入下一个坐标
  20.         while (flag)
  21.         {
  22.                 // 返回1表示成功找到落脚点
  23.                 if (setHorse(x1, y1, tag+1))
  24.                 {
  25.                         return 1;
  26.                 }
  27.                 // 否则从上一步重新尝试
  28.                 x1 = x;
  29.                 y1 = y;
  30.                 count += 1;
  31.                 flag = next(&x1, &y1, count);
  32.                 while (flag == 0 && count < 7)
  33.                 {
  34.                         count += 1;
  35.                         flag = next(&x1, &y1, count);
  36.                 }
  37.         }

  38.         if (flag == 0)
  39.         {
  40.                 chess[x][y] = 0;
  41.         }

  42.         return 0;
  43. }
复制代码
就可以。不知道问题在哪里。想知道是哪里错误了?

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

使用道具 举报

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

  4. #define X 8
  5. #define Y 8

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

  7. void print(void) {
  8.     int i, j;
  9.     for(i = 0; i < X; i++) {
  10.         for(j = 0; j < Y; j++) {
  11.             printf("%2d  ", chess[i][j]);
  12.         }
  13.         putchar('\n');
  14.     }
  15. }

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

  19.     switch(count) {
  20.     case 0:
  21.         if(x + 2 < X && y - 1 >= 0 && chess[x + 2][y - 1] == 0) {
  22.             *px = x + 2;
  23.             *py = y - 1;
  24.             return 1;
  25.         }
  26.         break;
  27.     case 1:
  28.         if(x + 2 < X && y + 1 < Y && chess[x + 2][y + 1] == 0) {
  29.             *px = x + 2;
  30.             *py = y + 1;
  31.             return 1;
  32.         }
  33.         break;
  34.     case 2:
  35.         if(x + 1 < X && y - 2 >= 0 && chess[x + 1][y - 2] == 0) {
  36.             *px = x + 1;
  37.             *py = y - 2;
  38.             return 1;
  39.         }
  40.         break;
  41.     case 3:
  42.         if(x + 1 < X && y + 2 < Y && chess[x + 1][y + 2] == 0) {
  43.             *px = x + 1;
  44.             *py = y + 2;
  45.             return 1;
  46.         }
  47.         break;
  48.     case 4:
  49.         if(x - 2 >= 0 && y - 1 >= 0 && chess[x - 2][y - 1] == 0) {
  50.             *px = x - 2;
  51.             *py = y - 1;
  52.             return 1;
  53.         }
  54.         break;
  55.     case 5:
  56.         if(x - 2 >= 0 && y + 1 < Y && chess[x - 2][y + 1] == 0) {
  57.             *px = x - 2;
  58.             *py = y + 1;
  59.             return 1;
  60.         }
  61.         break;
  62.     case 6:
  63.         if(x - 1 >= 0 && y - 2 >= 0 && chess[x - 1][y - 2] == 0) {
  64.             *px = x - 1;
  65.             *py = y - 2;
  66.             return 1;
  67.         }
  68.         break;
  69.     case 7:
  70.         if(x - 1 >= 0 && y + 2 < Y && chess[x - 1][y + 2] == 0) {
  71.             *px = x - 1;
  72.             *py = y + 2;
  73.             return 1;
  74.         }
  75.         break;
  76.     }
  77.     return 0;
  78. }

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

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


  85. #if 0
  86.     // ???
  87.     // 这是在做什么?
  88.     if(tag == 62) {
  89.         tag = 62;
  90.     }
  91. #endif


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

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

  98.         // 尝试路径是否能走
  99.         x1 = x; y1 = y;
  100.         //if(!decide_next(&x1, &y1, count)) {++count; continue;}
  101.         /*
  102.         resule = decide_next(&x1, &y1, count);
  103.         if(!resule) {
  104.             count += 1;
  105.         }
  106.         */
  107.         /*
  108.         // 这个for循环是在做什么?
  109.         // 这里需要两层循环吗?
  110.         for(x1 = x, y1 = y; resule == 0 && count < 8; count += 1) {
  111.             resule = decide_next(&x1, &y1, count);
  112.         }
  113.         */
  114.         // 返回1表示成功找到路径;对新的点进行尝试
  115.         if(decide_next(&x1, &y1, count)) {
  116.             if(setHorse(x1, y1, tag + 1)) return 1;
  117.         }
  118.         // 如果失败并且有没尝试的路径,回到上一步重新尝试
  119.         count += 1;
  120.     }
  121.     // 如果全部路径都尝试过,并且没有返回1,说明这个点没有可行的路径,回到上一步并且去除痕迹
  122.     chess[x][y] = 0;

  123.     return 0;
  124. }

  125. int main(void) {
  126.     int i, j, x, y;
  127.     clock_t start, finish;

  128.     for(i = 0; i < X; i++) {
  129.         for(j = 0; j < Y; j++) {
  130.             chess[i][j] = 0;
  131.         }
  132.     }

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

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

  139.     if(setHorse(x, y, 1)) {
  140.         print();
  141.     } else {
  142.         printf("可惜无解!\n");
  143.     }

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

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

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

  159. 本次计算一共耗时∶1.926012秒
  160. 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-5-1 04:07

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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