0

So looking at all of the other forums about solving a maze using recursion, none of them had helped me with my issue.

I get a maze from an input file and there is a start and end position. I find the start pos pass the x and y by reference and recursively solve the maze. My issue is that every possible spot in the maze is getting filled with a sign. When only the solution path should be marked (the '@' is what we are to use to show the path of the solution)

Here is what my code outputs when I complie and run:

    (2, 1)
    Found Exit
    |||||||||||
    |@@@|||@@@|
    |@|@@@@@|E|
    |||||||||||

    (5, 5)
    Found Exit
    ||||||||||||||||
    |@@@   |NNNN|N||
    |@|@||||N||NNN||
    |@|@@@@@@|||||||
    |@||||||@|E@@  |
    |@|||@@|@|||@|||
    |@|N||@|@@@@@|||
    |@|N||@||||||| |
    |@@@@@@        |
    ||||||||||||||||

    (1, 1)
    ||||||||||
    |NNN||  E|
    ||||||||||

As you can see, the 'N' are where the function found a dead end and needed to backtrack and erase them. The '@' sign is the correct path, it just doesn't erase when backtracking

I believe my issues is the the find_exit function or at_end function

Here is the code:

// "maze.h"

//header file
#include <iostream>
#include <string>

#ifndef MAZE
#define MAZE

using std::cout;
using std::endl;
using std::cin;
using std::string;


/*
Writes to a string array containing:
* the your (the student author’s) Campus Username (at index 0)
* and Student ID# (at index 1).
Takes as input a pre-existing length-2 string array.
*/
void get_identity(string my_id[]);


/**
Use this to help you enumerate the directions.
Gets passed into one function below.
**/
enum direction
{
    NORTH,
    SOUTH,
    EAST,
    WEST
};


/**
Creates a dynamically allocated array of strings.
Returns a pointer to that array.
**/
string * build_matrix(int rows);


/**
Fills the matrix with one line per string in the array.
Use the getline method.
Why don't you need to send in cols?
**/
void fill_matrix(string *matrix, int rows);


/**
Print the matrix as in the sample_output.txt
**/
void print_matrix(string *matrix, int rows);


/**
Delete the dynamically allocated array of strings.
Why don't you need to send in cols?
**/
void delete_matrix(string *matrix, int rows);


/**
Finds the starting position of Niobe.
Note: x and y are passed by reference; what does this do for you?
Why don't you need cols here? Hint: not the same reason as last two.
**/
void find_start(string *matrix, int rows, int &x, int &y);


/**
This is the recursive backtracking function you need to write.
It should return true if you found the solution,
and false if there is no solution.
It should leave a trail of @ signs along the path to the solution.
Make sure to build your solution with strong emphasis on the pseudocode;
do not try to code it first, first work out the solution on paper/markerboard.
**/
bool find_exit(string *matrix, int x, int y);


/**
Returns true if x and y are the final exit location,
and false otherwise.
**/
bool at_end(string *matrix, int x, int y);


/**
Returns true if the position indexed by x and y is a valid move,
and false otherwise.
What is a valid move?
**/
bool valid_move(string *matrix, int x, int y, direction d);


#endif
#include <fstream>
#include <limits>

using std::ifstream;

void get_identity(string my_id[])
{
    my_id[0] = "sra9wb";
    my_id[1] = "16781948";

    //output
    cout << "MST Campus Username: " << my_id[0] << endl;
    cout << "Student ID: " << my_id[1] << endl;
}

string *build_matrix(int rows)
{
    string *matrix = new string[rows]; //allocating memory for the matrix

    return matrix;
}

void fill_matrix(string *matrix, int rows)
{
    ifstream file_in("sample_input.txt");
    int x = 0;
    int y = 0;
    bool solved = false;

    while (file_in)
    {
        file_in >> rows;

        if (rows == 0)
            return;

        matrix = build_matrix(rows);

        file_in.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //Grab line until '\n' then toss it

        for (int i = 0; i < rows; i++)
        {
            getline(file_in, matrix[i]);//fillinf matrix with file_in from text file
        }
        find_start(matrix, rows, x, y);
        find_exit(matrix, x, y);
        print_matrix(matrix, rows);
        cout << endl;
        delete_matrix(matrix, rows);
    }
}

void print_matrix(string *matrix, int rows)
{
    for (int i = 0; i < rows; i++) //increment through the row of the matrix
    {
        cout << matrix[i] << endl; //print eack row
    }
}

void delete_matrix(string *matrix, int rows)
{
    delete[] matrix; //delete the matrix
    matrix = NULL;   //set equal to null for no hanging pointers
}

void find_start(string *matrix, int rows, int &x, int &y)
{
    for (int i = 0; i < rows; i++) //increment through the rows
    {
        string column;
        column = matrix[i]; //set the incremented row to string column

        for (int j = 0; j < column.length(); j++) //increment through the length of column
        {
            if (column[j] == 'N') //if the index of column matches N
            {
                x = i; //x is equal to i because of the 1st for loop
                y = j; //y is eqyal to j because of the 1st for loop
            }
        }
    }
    cout << "(" << x << ", " << y << ")" << endl;

}

bool find_exit(string *matrix, int x, int y) //first iteration of function passing in coords of N's starting pos
{
    //check if we reached the end of the maze
    if (at_end(matrix, x, y) == true)
        return true;

    //sets the starting position to @
    matrix[x][y] = 'N';

    //recursive search for out goal
    if (valid_move(matrix, x, y, NORTH) && find_exit(matrix, x - 1, y))
    {
        matrix[x][y] = '@';
        return true;
    }
    else if (valid_move(matrix, x, y, SOUTH) && find_exit(matrix, x + 1, y))
    {
        matrix[x][y] = '@';
        return true;
    }
    else if (valid_move(matrix, x, y, WEST) && find_exit(matrix, x, y - 1))
    {
        matrix[x][y] = '@';
        return true;
    }
    else if (valid_move(matrix, x, y, EAST) && find_exit(matrix, x, y + 1))
    {
        matrix[x][y] = '@';
        return true;
    }

    //this line here is meant to print a space when backtracking occurs
    // matrix[x][y] = ' ';   
    // return false;
}

//this function returns true if you are at the end of the maze
bool at_end(string *matrix, int x, int y)
{
    if (matrix[x][y] == 'E')
    {
        cout << "Found Exit" << endl;
        return true;
    }
    else
        return false;
}

bool valid_move(string *matrix, int x, int y, direction d)
{
    if (d == NORTH)
    {
        //check if north is clear
        if (matrix[x - 1][y] == ' ' || matrix[x - 1][y] == 'E')
            return true;
        else
            return false;
    }
    else if (d == EAST)
    {
        //check if EAST is clear
        if (matrix[x][y + 1] == ' ' || matrix[x][y + 1] == 'E')
            return true;
        else
            return false;
    }
    else if (d == SOUTH)
    {
        //check is south is clear
        if (matrix[x + 1][y] == ' ' || matrix[x + 1][y] == 'E')
            return true;
        else
            return false;
    }
    else if (d == WEST)
    {
        //check if west is clear
        if (matrix[x][y - 1] == ' ' || matrix[x][y - 1] == 'E')
            return true;
        else
            return false;
    }
    else
        return false;
}

//main

// #include "maze.h"



int main()
{
    string *matrix = NULL;
    int rows = 0;

    fill_matrix(matrix, rows);

    return 0;
}

The sample_input.txt document goes as follows:

4 11
|||||||||||
|   |||   |
|N|     |E|
|||||||||||

10 16
||||||||||||||||
|      |    | ||
| | |||| ||   ||
| |      |||||||
| |||||| |E    |
| |||N | ||| |||
| | || |     |||
| | || ||||||| |
|              |
||||||||||||||||

3 10
||||||||||
|N  ||  E|
||||||||||

0 0

These are the mazes that we are supposed to solve.

Also I am not allowed to edit the header file.

And this is how the output is supposed to look:

    Map 0 -- Solution found:
    |||||||||||
    |@@@|||@@@|
    |N|@@@@@|E|
    |||||||||||

    Map 1 -- Solution found:
    ||||||||||||||||
    |@@@   |    | ||
    |@|@|||| ||   ||
    |@|@@@@@@|||||||
    |@||||||@|E@@  |
    |@|||N@|@|||@|||
    |@| ||@|@@@@@|||
    |@| ||@||||||| |
    |@@@@@@        |
    ||||||||||||||||

    Map 2 -- No solution found:
    ||||||||||
    |N  ||  E|
    ||||||||||
11
  • 1
    Tried to build your code, but I get pages of error messages. Can we have an minimal reproducible example, please? Commented Feb 18, 2018 at 21:05
  • fixed @user4581301 Commented Feb 18, 2018 at 21:10
  • For starters, don't use new[] and delete[] (or new and delete). Use a standard container like std::vector<std::string>. Commented Feb 18, 2018 at 21:28
  • Not quite fixed. Put it all in one piece. No assembly required. Commented Feb 18, 2018 at 21:29
  • @JiveDadson this is a school assignment so I am supposed to use this.. :/ Commented Feb 18, 2018 at 21:32

2 Answers 2

1
//this line here is meant to print a space when backtracking occurs
        // matrix[x][y] = ' ';   
        // return false;

Why don't you just uncomment it? It solves your problem, but you have to add 'N' sign in start point manually after procedure as it replaces it with either '@' or ' ' (but it's easy).

Sign up to request clarification or add additional context in comments.

Comments

-1

FYI, setting the pointer to NULL (should be nullptr) accomplishes nothing here. The input parameter matrix takes a copy of the pointer ("by-value").

void delete_matrix(string *matrix, int rows)
{
    delete[] matrix; //delete the matrix
    matrix = NULL;   //set equal to null for no hanging pointers
}

2 Comments

Useful note, but since this has nothing to do with the problem in the question, why not a comment?
@user4581301 Because comments cannot contain formatted C++ code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.