How can i improve this code to show the shortest solution to the maze? [closed]

My question is why is this algorithm not attempting to go over water or soul sand even though that may be shorter. I am sorry you guys dont think this is a good question but i am a new coder and cannot figure out the issue. I have a minecraft based maze solving assignment in which i am given a maze as such:

9 10
1 1 

**********
*        *
*W**LL** *
*   LL   *
* * LL* **
*LL      *
*L*S**** *
*   E    *
********** 

where 9 10 are the dimenstions, 1 1 are the starting points, S is soul sand, W is water, L is lave, E is the end and * are walls. Any step on a blank space is 1 step, any step on water is 2 steps, and any step on soul sand is 3 steps. You are not allowed to step on walls or lave. Currently i have the following code:

#include "thpe23.h"

int main(int argc, char** argv)
{
    char** maze;
    int numRows, numCols, startRow, startCol, steps;
    int mazeNumber = 1;
    if (argc != 3)
    {
        usage();
        return 0;
    }

    ifstream fin;
    if (!openInput(argv[1], fin))
        return 1;

    ofstream fout;
    if (!openOutput(argv[2], fout))
        return 1;


    while (parseMaze(fin, numRows, numCols, startRow, startCol, maze))
    {
        cout << "Maze " << mazeNumber << ":" << endl;
        cout << "Size: " << numRows << " x " << numCols << endl;
        cout << "Starting Coordinates: " << startRow << " " << startCol << endl;
        solveMaze(maze, numRows, numCols, startRow, startCol);
        steps = countSteps(maze, numRows, numCols);
        cout << "Shortest Path: " << steps << " steps" << endl;
        printMaze(maze, numRows, numCols);
        fout << "Maze " << mazeNumber << ":" << endl;
        fout << "Size: " << numRows << " x " << numCols << endl;
        fout << "Starting Coordinates: " << startRow << " " << startCol << endl;
        fout << "Shortest Path: " << steps << " steps" << endl;
        writeMaze(fout, maze, numRows, numCols);

        mazeNumber++;
    }

    fin.close();
    fout.close();
    return 0;
}

void alloc(int numRows, int numCols, char**& maze)
{
    int i;

    maze = new char* [numRows];

    for (i = 0; i < numRows; i++)
    {
        maze[i] = new char[numCols];
    }
}


void dealloc(int numRows, char**& maze)
{
    int i;

    for (i = 0; i < numRows; i++)
    {
        delete[] maze[i];
    }
    delete[] maze;
    maze = nullptr;
}


bool openInput(string fileName, ifstream& fin)
{
    fin.open(fileName);
    if (!fin.is_open())
    {
        cout << "Unable to open file : " << fileName << endl;
        return false;
    }
    return true;
}


bool openOutput(string fileName, ofstream& fout)
{
    fout.open(fileName);
    if (!fout.is_open())
    {
        cout << "Unable to open file : " << fileName << endl;
        return false;
    }
    return true;
}


bool parseMaze(ifstream& fin, int& numRows, int& numCols, int& startRow,
    int& startCol, char**& maze)
{
    int i;

    fin >> numRows >> numCols >> startRow >> startCol;

    if (fin.fail())
        return false;

    fin.ignore(); // Ignore the newline character after startCol

    maze = new char* [numRows];

    for (i = 0; i < numRows; i++)
    {
        maze[i] = new char[numCols];
        fin.getline(maze[i], numCols + 1); // Read entire line, including whitespaces
    }

    return true;
}



int countSteps(char** maze, int numRows, int numCols)
{
    int steps = 0;
    int i, j;

    for (i = 0; i < numRows; ++i)
    {
        for (j = 0; j < numCols; ++j)
        {
            if (maze[i][j] == '-')
                steps++;
            else if (maze[i][j] == '=')
                steps += 2;
            else if (maze[i][j] == '+')
                steps += 3;
        }
    }
    return steps;
}


void writeMaze(ofstream& fout, char** maze, int numRows, int numCols)
{
    int i, j;

    for (i = 0; i < numRows; i++)
    {
        for (j = 0; j < numCols; j++)
        {
            fout << maze[i][j];
        }
        fout << endl;
    }
    fout << endl;
}

void solveMaze(char** maze, int numRows, int numCols, int startRow,
    int startCol)
{
    backTrack(maze, numRows, numCols, startRow, startCol);
}


bool isValid(char** maze, int numRows, int numCols, int newRow, int newCol)
{
    char dest;
    if (newRow >= 0 && newRow < numRows && newCol >= 0 && newCol < numCols)
    {
        dest = maze[newRow][newCol];
        if (dest == ' ' || dest == 'E' || dest == 'W' || dest == 'S')
            return true;
    }
    return false;
}

bool backTrack(char** maze, int numRows, int numCols, int currRow, int currCol)
{
    int i, newRow, newCol;
    char terrain;
    char symbol{};
    //all possible moves
    const int moves[][2] = { {-1, 0}, {0, 1}, {1, 0}, {0, -1} };

    if (maze[currRow][currCol] == 'E')
        return true;

    for (i = 0; i < 4; i++)
    {
        newRow = currRow + moves[i][0];
        newCol = currCol + moves[i][1];

        if (isValid(maze, numRows, numCols, newRow, newCol))
        {
            terrain = maze[newRow][newCol];

            if (terrain == ' ')
                symbol="-";
            else if (terrain == 'S')
                symbol="+";
            else if (terrain == 'W')
                symbol="=";
            else if (terrain == 'E')
                return true;

            markPath(maze, newRow, newCol, symbol);
            if (backTrack(maze, numRows, numCols, newRow, newCol))
                return true;

            markPath(maze, newRow, newCol, ' ');
        }
    }
    return false;
}

void markPath(char** maze, int row, int col, char mark)
{
    maze[row][col] = mark;
}

void usage()
{
    cout << "Usage: thpe23.exe inputMaze outputMaze" << endl;
}

void printMaze(char** maze, int numRows, int numCols)
{
    for (int i = 0; i < numRows; ++i)
    {
        for (int j = 0; j < numCols; ++j)
        {
            cout << maze[i][j];
        }
        cout << endl;
    }
    cout << endl;
}

which is outputting this:

Maze 1:
Size: 9 x 10
Starting Coordinates: 1 1
Shortest Path: 18 steps

**********
* -------*
*W**LL**-*
*   LL --*
* * LL*-**
*LL    --*
*L*S****-*
E----*
**********

which is a solution but not actually the shortest paththis is the correct solution to the maze above How can i update my code to correctly find the shortest path even if that means going over water or soul sand?

  • This is not a question and should not be posted here.

    – 

  • We’d like to help. Please edit your question, and ask something specific. Thanks.

    – 

  • 1

    Generalization: If you don’t have the slightest clue where the problem is A) you’re asking the question too soon and need to do more debugging and B) you probably have more than one problem. Back up the program then replace all of the file IO with a hard-coded array. This eliminates problems with the file IO. Then hack away other bits of code not related to the bug you’re trying to isolate until you have a very small program that is nothing but bug. Usually you don’t get that far because you spot and fix the bug.

    – 

  • Hard-coding a maze for testing is a good idea. It is easy to get sidetracked in the details of I/O, and never get to the business of solving a maze. Right now, for instance, you have solid routines, alloc and dealloc for handling dynamic storage, but you are not calling them. Function parseMaze leaks memory, because it does its own allocation, right on top of the prior one. So, hard-code a maze, and fix parseMaze later.

    – 

  • Cplusplus puts it consisely: “std::istream::getline Extracts characters from the stream as unformatted input and stores them into s as a c-string, until either the extracted character is the delimiting character, or n characters have been written to s (including the terminating null character).” Looks like you have a buffer overrun in function parseMaze.

    – 

Leave a Comment