2

I'm trying to make my C program solve a maze, using backtracking.

Basically, what the program does is taking a file inserted as a command line argument (the file should contain the maze structure) and try to "solve it", outputting each step made.

The maze-walls are hashtags (#), and the program should avoid them. Every step made should be marked with dot (.). The program can only step on spaces ( ).

The maze starts from the symbol S (Start), and should reach the symbol E (End).

An example of how a maze should look like is like this:

enter image description here

The maze data is stored in a matrix a[1000][1000], 1000 defined as MAX in my program. Every time I make a step on a certain position on the matrix a[y][x], a[y][x] should be transformed into a dot (.).

I'm using the usleep() function, to output the matrix every 80 000 nanoseconds, so that the user can see every step properly.

Everything works (almost fine). When the maze reaches a certain point when it cannot go further, it deletes all the previous steps until it finds another way. The problem is, it deletes more "dots" than it is intended to delete. And (I think) this is the reason it'll never get to the E point.

Information about the code:

These are my global variable declarations:

int i_MAX, j_MAX;

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

where i_MAX and j_MAX are used to compute the size of the maze array a.

The main() function only contains the procedure of procuring the file from the command-line argument, together with computing i_MAX and j_MAX, and also the call back(0).

These are the functions that (in my opinion) cause trouble:

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, int step_X, 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, step_X, a);
            a[step_Y][step_X] = ' ';
        }
    }
}

I am pretty sure the problem lays in the last line of the bck() function, when trying to "reset" the invalid position:

a[step_Y][step_X] = ' ';

I tried changing that line in numerous ways, although I still couldn't make the program work properly.

What am I doing wrong? Does it have to do with some other part of the code?

P.S. here's my maze text:

################################################################################
#S                                                                  #          #
################################################################### # ######## #
#                                                           ####### # ##    ## #
# ######################################################### #       # ## ## ## #
# # #E                                                    # ####### # ## ## ## #
# # ##################################################### #         # ## #  ## #
# #                                                       ######### # ## ## ## #
# ####################################################### # #       # ## ## ## #
# #                                                         # ##### # ## ## ## #
# # ####################################################### # # ### # ## ## ## #
# # #        #########################                      # #     # ## ## ## #
# # # ######                         ######################## ##### # ## ## ## #
# # # ## ### ####################### # ##     ###     ##    ##    # # ## ## ## #
# # #  #     #                       #    ###     ###    ##    #### # ## ## ## #
# # ## ############################# # ############################ # ## ## ## #
# # ## #                        ###  #                            # # ## ## ## #
# # ## # ########### ############   ## ############################## ## ## ## #
# #    #           # #            ####                                #  ###   #
# ################ # ####### ######### ##############################   #### # #
#                # # #                                            # ########## #
######## ######### # ############################################## #          #
#                  #                                                  ### ######
################################################################################
Jens
  • 69,818
  • 15
  • 125
  • 179
Mateaș Mario
  • 113
  • 1
  • 7
  • 2
    Try to find the *smallest* and *simplest* maze possible that triggers the problem. Then use a debugger to step through the code line by line (while monitoring variables and their values) to see what's really happening. Or use a lot of debug `printf` calls, printing variable-values and states and everything else. – Some programmer dude Apr 17 '21 at 22:10
  • 1
    Be careful with the condition `a[step_Y][step_X] == ' ' && step_Y >= 0 && step_X >= 0 && step_Y < i_MAX && step_X < j_MAX`. If `step_Y` or `step_X` is negative (or larger than `i_MAX` and `j_MAX`) you will go out of bounds of your array before you check the bounds. – Some programmer dude Apr 17 '21 at 22:14
  • @Someprogrammerdude Using a bunch of printf's only spams my console log and I'm not able to look over all of them – Mateaș Mario Apr 17 '21 at 22:18
  • 1
    Write them to a file, or use a debug print so it only comes out in the debugging console. Also, paste your maze as text so we don't have to type one in. – Mark Tolonen Apr 17 '21 at 22:19
  • 1
    You could add debug printing to only a section of the code, and of everything is okay there then remove them and add new printing in another section of the code. Or as mentioned by @MarkTolonen, write it to a file that you can go through after the run. – Some programmer dude Apr 17 '21 at 22:20
  • @MarkTolonen pasted the maze text in my question – Mateaș Mario Apr 17 '21 at 22:25

1 Answers1

1
  • Function : is_solution

E (end) is not necessarily i_MAX and j_MAX. In your example, it is step_Y=5 and step_X=5

  • Function: bck

Recursive problem : You change step_X ans step_Y before recursively calling bck. But, if this way is a cul-de-sac, before trying another direction, you have to restore step_X and step_Y to their original values.

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];
        }
    }
}
Stef1611
  • 1,978
  • 2
  • 11
  • 30