尝试复制迷宫算法

问题描述

我正在尝试使用回溯法让我的 C 程序解决迷宫问题。

基本上,程序所做的是将插入的文件作为命令行参数(该文件应包含迷宫结构)并尝试“解决它”,输出所做的每一步。

迷宫墙是 hashtags (#),程序应该避开它们。所做的每一步都应标有 dot (.)。程序只能踩空格( )

迷宫从符号 S (Start) 开始,应该到达符号 E (End)

迷宫应该是什么样子的一个例子是这样的:

enter image description here

迷宫数据存储在我的程序中定义为 a[1000][1000] 的矩阵 1000MAX 中。每次我在矩阵 a[y][x] 上的某个位置上迈出一步,a[y][x] 都应该转化为 dot (.)

我正在使用 usleep() 函数,每隔 80 000 nanoseconds 输出矩阵,以便用户可以正确地看到每一步。

一切正常(几乎没问题)。当迷宫到达某个点而无法进一步前进时,它会删除之前的所有步骤,直到找到另一条路。问题是,它删除的“点”比打算删除的要多。而且(我认为)这就是它永远不会到达 E 点的原因。

关于代码的信息:

这些是我的全局变量声明:

int i_MAX,j_MAX;

int dy[4] = {-1,1,0};
int dx[4] = {0,-1,1};

其中 i_MAXj_MAX 用于计算迷宫数组 a 的大小。

main() 函数仅包含从命令行参数获取文件的过程,以及计算 i_MAXj_MAX,以及调用 back(0)

这些是(在我看来)造成麻烦的函数

int is_acceptable(int step_Y,int step_X,int i,char a[MAX][MAX]) {
    // check if it is possible to move the current point (step_X,step_Y)
    // to the position (step_X+dx[i],step_Y+dy[i])
    step_Y += dy[i];
    step_X += dx[i];
    if (a[step_Y][step_X] == ' ' && step_Y >= 0 && step_X >= 0 
                                 && step_Y < i_MAX && step_X < j_MAX)
        return 1;
    return 0;
}

int is_solution(int step_Y,int step_X) {
    if (step_Y == i_MAX && step_X == j_MAX) return 1;
    return 0;
}

void bck(int step_Y,char a[MAX][MAX]) {
    // test
    system("clear");
    for (int w = 0; w<i_MAX; w++) {
            for(int x = 0; x<j_MAX; x++)
            putchar(a[w][x]);
        printf("\n");
    }
    usleep(80000);
    // end test
    for (int i = 0; i<=3; i++) {
        if (is_acceptable(step_Y,step_X,i,a)) {
            step_Y += dy[i];
            step_X += dx[i];
            a[step_Y][step_X] = '.';
            if (is_solution(step_Y,step_X)) {
                for (int w = 0; w<i_MAX; w++) {
                    for(int x = 0; x<j_MAX; x++)
                        putchar(a[w][x]);
                printf("\n");
                }
            }
            else bck(step_Y,a);
            a[step_Y][step_X] = ' ';
        }
    }
}

我很确定问题出在 bck() 函数的最后一行,当试图“重置”无效位置时:

a[step_Y][step_X] = ' ';

我尝试以多种方式更改该行,但仍然无法使程序正常运行。

我做错了什么?是否与代码的其他部分有关?

附言这是我的迷宫文字

################################################################################
#S                                                                  #          #
################################################################### # ######## #
#                                                           ####### # ##    ## #
# ######################################################### #       # ## ## ## #
# # #E                                                    # ####### # ## ## ## #
# # ##################################################### #         # ## #  ## #
# #                                                       ######### # ## ## ## #
# ####################################################### # #       # ## ## ## #
# #                                                         # ##### # ## ## ## #
# # ####################################################### # # ### # ## ## ## #
# # #        #########################                      # #     # ## ## ## #
# # # ######                         ######################## ##### # ## ## ## #
# # # ## ### ####################### # ##     ###     ##    ##    # # ## ## ## #
# # #  #     #                       #    ###     ###    ##    #### # ## ## ## #
# # ## ############################# # ############################ # ## ## ## #
# # ## #                        ###  #                            # # ## ## ## #
# # ## # ########### ############   ## ############################## ## ## ## #
# #    #           # #            ####                                #  ###   #
# ################ # ####### ######### ##############################   #### # #
#                # # #                                            # ########## #
######## ######### # ############################################## #          #
#                  #                                                  ### ######
################################################################################

解决方法

  • 功能:is_solution

E (end) 不一定是 i_MAX 和 j_MAX。在您的示例中,它是 step_Y=5 和 step_X=5

  • 函数:bck

递归问题:您在递归调用 bck 之前更改 step_X 和 step_Y。但是,如果这种方式是死胡同,那么在尝试另一个方向之前,您必须将 step_X 和 step_Y 恢复为它们的原始值。

void bck (int step_Y,int step_X,char a[MAX][MAX]) {
    // test
    ...
            else bck(step_Y,step_X,a);
            a[step_Y][step_X] = ' ';
            step_Y -= dy[i];
            step_X -= dx[i];
        }
    }
}