Search code examples
c++recursionstackoverflowmaze

c++ maze solver (find every solution) stack overflow


I have an assignment to randomly generate a maze ("weird" ones are valid as well), then I have to find all solutions for the maze (a solution being finding a way from the first row or column to the last row or column), also determine the shortest one. I have this code here, but when I run it, half the time it gives a good answer, the other half time it just exits without any error popup or warning. I guess the reason would be stack overflow. Also, in the assignment it said we had to solve this on a 20x20 maze. If it overflows on a 5x5, can you imagine a 20x20? Anyway, any help would be greatly appreciated. Please ignore the comments, it's actually part of the assignment to have Hungarian comments.

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

struct vector2d {
    int column, row;
};

const int N = 5;        // sorok száma
const int M = 5;        // oszlopok száma
bool ut[N][M];
int count = 0;
int currentLength = 0, minLength = 99999;

void initMaze();         // generál egy labirintust
void printMaze();        // kiiratja a labirintust
int exits();             // kijáratok számát adja vissza
int entrances();         // bejáratok számát adja vissza
bool findPath(int, int); // útkereső eljárás

int main() {
    initMaze();
    printMaze();
    if (exits() > 0 && entrances() > 0) {
        // bactrack
        for (int i = 0; i < M; i++) // vegigjarjuk az elso sor osszes "utjat" es megkeressuk az onnan indulo megoldasokat
            if (ut[0][i])
                if (findPath(0, i)) {
                    count++;
                    if (currentLength < minLength)
                        minLength = currentLength;
                    currentLength = 0;
                }

        for (int i = 1; i < M; i++)
            if (ut[i][0])
                if (findPath(i, 0)) {
                    count++;
                    if (currentLength < minLength)
                        minLength = currentLength;
                    currentLength = 0;
                }
    } else {
        cout << "Maze has no entrances or exits" << endl;
    }

    if (count > 0) {
        cout << count << " solutions for the labyrinth, shortest one is " << minLength << " steps long" << endl;
    } else {
        cout << "Labyrinth has no solution" << endl;
    }

    system("pause");
    return 0;
}

int exits() {
    int count = 0;
    for (int i = 1; i < M - 1; i++)
        if (ut[N - 1][i])
            count++;
    for (int i = 1; i < N - 1; i++)
        if (ut[i][M - 1])
            count++;
    return count;
}

int entrances() {
    int count = 0;
    for (int i = 1; i < M - 1; i++)
        if (ut[0][i])
            count++;
    for (int i = 1; i < N - 1; i++)
        if (ut[i][0])
            count++;
    return count;
}

void initMaze() {
    srand(time(NULL));
    for (int i = 0; i < N; i++)
        for (int j = 0; j < M; j++) {
            if (rand() % 3 == 0) // 3-ból egyszer legyen fal
                ut[i][j] = false;
            else
                ut[i][j] = true;
        }
}

void printMaze() {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (ut[i][j])
                cout << " - ";
            else
                cout << " | ";
        }
        cout << endl;
    }
}

bool findPath(int row, int column) {
    if (column < 0 || column > N - 1 || row < 0 || row > M - 1) return false;
    if ((column == M - 1 || row == N - 1) && ut[row][column])   return true;
    if (!ut[row][column])                                       return false;
    currentLength++;
    if (findPath(column + 1, row))                              return true;
    if (findPath(column, row + 1))                              return true;
    if (findPath(column - 1, row))                              return true;
    if (findPath(column, row - 1))                              return true;
    currentLength--;
    return false;
}

Solution

  • You have the recursive call

    findPath(column + 1, row)
    

    This function will after a while come to this recursive call

    findPath(column - 1, row)
    

    The problem with these two calls is that will go back to the location it was called from.

    For example, if findPath is called with the coordinates 2,4, then the first call shown will call findPath(3,4), which will then call findPath(2,4) (which of course will call findPAth(3,4) and so on and so on in infinity).