Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 16

MazeAssignment.

cpp
CS 121 Bolden --------- g++ (gcc) 11.2.0 --------- Luke Maupin
4/7/2023 --------- Windows 10, Ryzen 5 3600 --------- maup8702@vandals.uidaho.edu

Overview:
In this program, we will traverse through a given maze through the use of our array and
queues. We will move through the maze by scanning the adjacent spots in the maze to see if it's
in bounds, an unvisited location, or the exit. Once we have made it to the end of the maze the
movement loop will stop and the program will end.

1. Include the queue.h file to allow the use of queues.


2. A dynamic 2 dimensional array of integers is created.
3. User inputs the name of the file containing the maze they want solved.
4. Used ifstream to open the file.
5. The first line will give us the amount of rows and columns in the maze.
6. Save each row of the maze to a string, then walk through the string assigning each spot in
the string to its spot in the array.
7. Use a loop to find the starting point in the array by searching for the ‘S’ character.
8. In a while loop:
● Use an if statement to look at the adjacent spaces, and if they are in bounds and
are a period, add that location to the queue and replace the period with an arrow.
● After checking the adjacent locations, use a peek function to get the next location
in the maze.
● Take the current location out of the queue.
● Print the maze
● Use the byGoal() function to check if the end of the maze has been reached. If it
has, exit the loop.
9. printMaze() function:
● Uses a nested for loop to print each column then moves down a row after its
finished. Repeat until the whole maze is printed.
10. byGoal() function:
● Similarly to the loop used to move through the maze, if statements will be used to
check the adjacent locations in the maze. If the ‘G’ character is found, then we are
by the exit and a number will be returned that will stop the movement loop.
11. print2() function:
● Will only print the maze every so many loops so that there aren't a million things
from output.

I estimate that it will take me around 5 hours to fully implement the program and fix any
issues that come up during the process.
Programing Log:

4/5/2023

7:00 Started setting up the files I knew I would need for the assignments.
7:05 Created the main file, the programming log file, and the file the maze is read from
7:14 I repurposed the dynamic array I used in the last assignment and coded the opening of the
file storing the maze layout
7:30 I used ifstream to take the number of rows and columns and store them in variables. Also, I
created a loop to store the characters of the maze in the array.
7:39 Made a new function to print out the maze so I can use it for testing as I get further along.
7:58 Decided to change how I opened the files to make it easier. Now the user types in the file
name and it gets saved to a string then it is opened.
8:00 I also decided to change how the characters are saved to the array because currently I'm
using ifstream, so I would have to put a space in between each character to make it work. This
would be painful for the 40 by 40 maze.
8:12 I finished changing how the maze is saved to the array. I did it by saving a row of the maze
to a string, then walking through the string, saving each character of the string to its spot in the
array.
9:24 I worked on writing the queue file. I can now add to, take away from, and peek at elements
of a queue.
9:57 I created the queue in the program and used a for loop to find the start point of the maze.
10:28 The program can now find the starting point, check the adjacent spots for periods, change
the symbol to the corresponding arrow and get added to the queue.

4/6/2023

12:07 I am having problems with my queue. It doesn't look like anything is getting added to it.
12:29 I have fixed the issue with the queue. The problem was in the Enqueue function I
accidentally set n -> y = x so one of the argument values coming in was never getting looked at
which broke everything.
12:37 After more testing, it's not entirely fixed. I changed the starting location and it no longer
works. I suspect that there could be an issue when the location moves left and/or down.
12:45 In my testing I found out that I deleted a -1 from the up movement if statement argument.
Up is now fixed, but I think the left movement is still broken.
12:47 I found an error with the left movement. I accidentally typed the wrong sign so it was
moving the wrong direction.
12:49 Hopefully the issues are fixed now, I will do more testing later.
3:51 Spent a few minutes adding proper comments to make the code easier to follow.
9:30 Starting work on adding the function that will make it so the maze is only printed every few
times the loop repeats.
9:56 I think I'm done with the function. I'm going to do some final testing and then I am finished
with the program.
10:03 I added a cout to the queue.h that says the maze can't be complete if it tries to take
something out of the queue without something being in it.
10:09 The program is complete

Source Code:

MazeAssignment.cpp
#include <iostream>
#include <fstream>
#include "queue.h"

using namespace std;

// Prototypes
void printMaze(int, int, char**);
int byGoal(int, int, char**, int, int);
void print2(int, int, char**, int);

int main()
{
// String to store file name
string file;

cout << "Enter the name of the file your maze is stored in (Include file extension): ";
cin >> file;

// Opens the file containing the maze layout


ifstream infile;
infile.open(file);

// Variables storing number of rows & columns


int rows;
int cols;

// Takes the amount of rows and columns from file and saves them in variable
infile >> rows >> cols;

// Dynamic Array
char ** arr2D = new char *[rows];
for( int i = 0; i < rows; i++ )
{
arr2D[i] = new char[cols];
}

// Stores the maze in an array


string line; // Saves the characters in a row to a string

for(int i = 0; i < rows; i++)


{
infile >> line; // Stores the row into the string
for(int j = 0; j < cols; j++)
{
arr2D[i][j] = line[j]; // Saves each character of the string to the array then repeats until maze is saved
}
}

// Creating queue
Queue queue;

int currentRow;
int currentCol;

// Searching for the start point of the maze


for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
{
if(arr2D[i][j] == 'S')
{
currentRow = i;
currentCol = j;
}
}
}

// Checking the locations adjacent to the current spot in the maze


int exitLoop = 0;
int totalIterations = 0;

do{
if((currentRow != 0) && (arr2D[currentRow - 1][currentCol] == '.')) // Move up
{
queue.Enqueue(currentRow - 1, currentCol); // Adds the location to the queue
arr2D[currentRow - 1][currentCol] = '^'; // Replaces the period with an arrow showing what direction it
moves
}

if((currentCol != (cols - 1)) && (arr2D[currentRow][currentCol + 1] == '.')) // Move right


{
queue.Enqueue(currentRow, currentCol + 1); // Adds the location to the queue
arr2D[currentRow][currentCol + 1] = '>'; // Replaces the period with an arrow showing what direction it
moves
}

if((currentRow != (rows - 1)) && (arr2D[currentRow + 1][currentCol] == '.')) // Move down


{
queue.Enqueue(currentRow + 1, currentCol); // Adds the location to the queue
arr2D[currentRow + 1][currentCol] = 'v'; // Replaces the period with an arrow showing what direction it
moves
}

if((currentCol != 0) && (arr2D[currentRow][currentCol - 1] == '.')) // Move left


{
queue.Enqueue(currentRow, currentCol - 1); // Adds the location to the queue
arr2D[currentRow][currentCol - 1] = '<'; // Replaces the period with an arrow showing what direction it
moves
}

totalIterations++;

currentRow = queue.PeekX(); // Getting the next row location to send into the loop
currentCol = queue.PeekY(); // Getting the next col location to send into the loop

queue.Dequeue(); // Taking last location out of the queue

print2(rows, cols, arr2D, totalIterations);

exitLoop = byGoal(currentRow, currentCol, arr2D, rows, cols); // Check if we're by the exit
}while(exitLoop == 0);

cout << "Completed Maze: " << endl; // Prints the final version of the maze
printMaze(rows, cols, arr2D);

cout << "Total Iterations: " << totalIterations << endl; // Prints the amount of times the loop repeated before
finishing

system("Pause");
}

void printMaze(int r, int c, char** arr)


{
for(int i = 0; i < r; i++)
{
for(int j = 0; j < c; j++)
{
cout << arr[i][j];
}
cout << endl;
}
cout << endl;
}

int byGoal(int currentRow, int currentCol, char** arr2D, int rows, int cols)
{
if(currentRow != 0 && arr2D[currentRow - 1][currentCol] == 'G') // Check if currently by goal
{
return 1; // Return 1 to exit loop
}

if(currentCol != cols - 1 && arr2D[currentRow][currentCol + 1] == 'G') // Check if currently by goal


{
return 1;
}

if(currentRow != rows - 1 && arr2D[currentRow + 1][currentCol] == 'G') // Check if currently by goal


{
return 1;
}

if(currentCol != 0 && arr2D[currentRow][currentCol - 1] == 'G') // Check if currently by goal


{
return 1;
}

return 0; // Return 0 to continue loop


}

void print2(int r, int c, char** arr, int iterations)


{
if(r < 7 && (iterations % 3) == 0) // Makes it so the maze only prints every 3 times through the loop when it has
less than 7 rows
{
printMaze(r, c, arr);
}

if(r >=7 && r < 15 && (iterations % 15) == 0) // Makes it so the maze only prints every 12 times through the
loop when it has between 7 and 15 rows
{
printMaze(r, c, arr);
}

if(r >= 15 && r < 25 && (iterations % 50) == 0) // Makes it so the maze only prints every 50 times through the
loop when it has between 15 and 25 rows
{
printMaze(r, c, arr);
}
if(r >= 25 && (iterations % 200) == 0) // Makes it so the maze only prints every 200 times through the loop when
it has more than 25 rows
{
printMaze(r, c, arr);
}
}

queue.h
#include <iostream>

using namespace std;

class Queue
{
private:

struct node
{
int x;
int y;
node* next;
};

node* front;
node* end;
public:
Queue();
void Enqueue(int, int);
void Dequeue();
int PeekX();
int PeekY();
bool IsEmpty();
void Print();
};

Queue::Queue()
{
front = NULL;
end = NULL;
}

void Queue::Enqueue(int x, int y)


{
node* n = new node;
n -> x = x;
n -> y = y;
n -> next = NULL;
if(IsEmpty())
{
front = end = n;
}else{
end -> next = n;
end = n;
}
}

void Queue::Dequeue()
{
if(IsEmpty())
{
cout << "Maze cannot be complete." << endl;
// cout << "Queue is Empty." << endl;
}else{
node* temp = front;
front = front -> next;
delete temp;
}
}

bool Queue::IsEmpty()
{
return {front == NULL};
}

int Queue::PeekX()
{
if(IsEmpty())
{
// cout << "Queue is Empty." << endl;
return -1;
}else{
return front -> x;
}
}

int Queue::PeekY()
{
if(IsEmpty())
{
// cout << "Queue is Empty." << endl;
return -1;
}else{
return front -> y;
}
}
void Queue::Print()
{
node* temp = front;

while(temp != NULL)
{
cout << temp -> x << ", " << temp -> y;
cout << endl;
temp = temp -> next;
}
}

Maze1.txt
55
S....
.##.#
.#...
.#.#.
...#G

Maze2.txt
10 10
S##.#..##.
..........
#..#.#.#..
.#.#...###
.....#....
.#.###.##.
.#.#...###
.#.#.#....
........#.
##..##..#G
Maze3.txt
20 20
....#....#####S.#..#
.##...#....#......#.
...##...#.#..#.###..
##.#...##...##.####.
#..##.#...#.....#...
..###......#.##....#
..###.##..#.##..#...
#.......#.###.#.....
#...###....###.###..
..#...#.#....##...#.
.##..#..#.##..###.#.
.#...#.#.#..#....#..
..##.#..#####.##.##.
.#.......####..###..
....####.#....#...#.
##.#.#....##...###..
.#.....#.#.#.......#
.#.##..#.....#.###.#
....#..##.###...##.#
#...#.....#####G...#
Maze4.txt
40 40
###......##.....##....######........#..S
#...####...###.##.##.#..##...######...#.
.#....#......##.......##....##....#.###.
#.#......##.....##..#...#.##..##.#######
##.....##..#..#...####.###.###....####..
..#..#.##.#.#..##.#...#...#..##.#.####.#
.#...#.....#.##.######...###.....#.....#
....#.##.#..#.##..#.####..##..##....####
.###..#....#...#.#.#.#..#.####.......###
..###.#.##..#...#.##.########....##.###.
#......###.#..##..##....##.#####..###.#.
.###.##..#.#.##.#..#........#....###.#..
.###.##.......#..#.###..######.###....#.
..##.#.#...##..####.####..#########.#..#
##...###.......###..###.##.######..#.##.
..##...###.##...#..##..#...########..##.
.###.##..#..##..#.#..#..#...##.#..#.....
..##.#..#.##.##....##.##.#####.###.##..#
####....##..###.#....####..##......####.
..#....#..#.#...##.##.##.##....###...#..
....##.....#.###.#..#.#..##.###...###.#.
.###...##.#..##..##........#.#.#..#..##.
#.#.#...#.#####.#..#..#..#...#..#..#.#.#
.###.##.......#...#..#..####..####.####.
..###....#..##.#...###..####...#..###..#
.##..###..#####.#.#...#..##........#..#.
.#.##....#..##...#.###.#.....#...#..###.
..#.###...#...#......###.##.#.#...#.#...
.###.##.#..#.##.##.##..###....#..#...###
###.##.#.#..#..#..###.#..#...####.##....
.####.#.##...##.##...#.#..##.##..###.##.
#.#..#..#.##...##..##.#...###.###.#.##..
...#..####..##.......#.#...###.#....#...
.##....##.##..#.###.###.###...####.#...#
...##...##...#...#.....#..##..##...#..##
##......#.##...###..#....#...######.#...
.....##..#..#..##..#.##....#...#.....##.
.##..##.#.....########.#.###########....
.#.#.#....##...##.....##....####.....##.
G...###.###........######........#######
Output:

Maze 1 Output

Maze 2 Output
Maze 3 Output Part 1
Maze 3 Output Part 2
Maze 4 Output

You might also like