Uploaded by Hussein Mahmoud

Report of Data Structures project

advertisement
AMERICAN UNIVERSITY OF SCIENCE & TECHNOLOGY
FACULTY OF ARTS AND SCIENCES
CSI/ICT Department
CSI-391 – Data Structures and Algorithms
Maze solving
By
Ahmad Dib -12200384Rayen Kamal -12200426Hussein Mahmoud -12202047Adam Kanso-12212035Submitted to
Dr. David Semaan
Achrafieh, Lebanon
January,8,2023
P a g e i | 13
Abstract
Maze Solver
This project addresses a program that we developed in C++. The making of this
code was a good and fun way to practice the skills and knowledge we learned
throughout the Data Structures course. This research paper targets university
students. It presents the objectives of the app, a brief explanation and introduction,
a detailed account of the design and procedures included in the creation of this app
as well as a description of the problems faced and proposed solutions.
P a g e 2 | 13
Table of Contents
Abstract ......................................................................................................................................... 2
Table of Contents .......................................................................................................................... 3
I.
Introduction ........................................................................................................................ 4
II.
Objectives............................................................................................................................ 4
III.
Background ........................................................................................................................ 4
IV.
Program and Problem Definition ..................................................................................... 4
V.
Problems Faced and Solutions .......................................................................................... 5
VI.
Code With Explanation .................................................................................................... 5
VII.
Conclusion………………………………………………………………14
P a g e 3 | 13
I. Introduction
We wanted to apply what we learned in Data Structures to develop our first App that is a maze
solving program coded to show us both the traversal stack and queues (BFS and DFS) from the
entrance to the exit.
II. Objectives
1- Create an app while applying the skills we acquired during our sessions.
2- Using DFS get the app to show the traversal stack.
3- Using BFS get the app to show the traversal queue.
III.
Background
We were asked to create a C++ Maze Solver for our final project in our Data Structures course.
We found that creating this app using C++ is a fun and creative way of applying what we learned
throughout the semester, in addition to using external sources such as the internet to aid us in
completing this project and further our understanding of coding.
IV.
Program and Problem Definition
The project is addressing the problem which is creating a mistake free and efficient app that
shows you both the traversal stack for a maze using the DFS method, and the traversal queue for
the BFS method going from the entrance to the exit.
P a g e 4 | 13
V. Problems Faced and Solutions
A. Our first error was us following the old map where nodes 1 and 12 were neighbors.
B. We fell into syntax errors that are normal while coding and were easy to fix.
C. The start node was initialized in a wrong way at first which caused a problem, and it was
fixed by initializing the node start_pos at n1.
VI.
Code With Explanation
#include <iostream>
#include <queue>
#include <unordered_map>
#include <stack>
// We create the structure of the nodes in the graph
struct Node {
// We assign a value to the node.
int value;
// The list of neighbors of the node using a vector
std: vector<Node*> neighbors;
bool exit = false;
};
P a g e 5 | 13
// We created a structure for the graph that will hold the nodes.
class Graph {
public:
// The list of nodes in the graph.
std::vector<Node*> nodes;
// BFS Function
void BFS(Node* start) {
// Create a queue to hold the nodes that we need to visit.
std::queue<Node*> q;
// Create a map to track which nodes have been visited.
std::unordered_map<Node*, bool> visited;
// Add the start node to the queue and mark it as visited.
q.push(start);
visited[start] = true;
// While the queue is not empty...
while (!q.empty()) {
// Get the next node to visit.
Node* current = q.front();
//Pop every node the current visits
q.pop();
// Print the value of the current node.
std::cout << current->value << std::endl;
// If the current gets to the exit the loop breaks
if (current->exit) {
break;
}
P a g e 6 | 13
// Add all of the unvisited neighbors of the current node to the queue.
for (Node* neighbor : current->neighbors) {
if (!visited[neighbor]) {
q.push(neighbor);
visited[neighbor] = true;
}
}
}
};
// This function performs a depth-first search starting from the given start node.
void DFS(Node* start) {
// Create a map to track which nodes have been visited.
std::unordered_map<Node*, bool> visited;
// Create a stack to hold the nodes that we need to visit.
std::stack<Node*> s;
// Add the start node to the stack and mark it as visited.
s.push(start);
visited[start] = true;
// While the queue is not empty...
while (!s.empty()) {
// Get the next node to visit.
Node* curr = s.top();
//Pop every node the current visits
s.pop();
// Print the value of the current node.
std::cout << curr->value << std::endl;
// If the current gets to the exit the loop breaks
if (curr->exit) {
P a g e 7 | 13
break;
}
// Add all of the unvisited neighbors of the current node to the stack.
for (Node* neighbor : curr->neighbors) {
if (!visited[neighbor]) {
s.push(neighbor);
visited[neighbor] = true;
}
}
}
// Print the value of the start node.
}
};
int main()
{
// Create a graph.
Graph g;
// Create the nodes.
Node* n1 = new Node{ 1 };
Node* n2 = new Node{ 2 };
Node* n3 = new Node{ 3 };
Node* n4 = new Node{ 4 };
Node* n5 = new Node{ 5 };
Node* n6 = new Node{ 6 };
Node* n7 = new Node{ 7 };
Node* n8 = new Node{ 8 };
P a g e 8 | 13
Node* n9 = new Node{ 9 };
Node* n10 = new Node{ 10 };
Node* n11 = new Node{ 11 };
Node* n12 = new Node{ 12 };
//Push the nodes to the graph.
g.nodes.push_back(n1);
g.nodes.push_back(n2);
g.nodes.push_back(n3);
g.nodes.push_back(n4);
g.nodes.push_back(n5);
g.nodes.push_back(n6);
g.nodes.push_back(n7);
g.nodes.push_back(n8);
g.nodes.push_back(n9);
g.nodes.push_back(n10);
g.nodes.push_back(n11);
g.nodes.push_back(n12);
// Assign the neighbors to each other in the graph.
n1->neighbors.push_back(n2);
n1->neighbors.push_back(n10);
n2->neighbors.push_back(n3);
n2->neighbors.push_back(n9);
n2->neighbors.push_back(n1);
n3->neighbors.push_back(n2);
n3->neighbors.push_back(n4);
n4->neighbors.push_back(n3);
n4->neighbors.push_back(n9);
n4->neighbors.push_back(n5);
n5->neighbors.push_back(n4);
P a g e 9 | 13
n5->neighbors.push_back(n6);
n6->neighbors.push_back(n5);
n6->neighbors.push_back(n9);
n6->neighbors.push_back(n7);
n7->neighbors.push_back(n6);
n7->neighbors.push_back(n9);
n7->neighbors.push_back(n8);
n8->neighbors.push_back(n7);
n8->neighbors.push_back(n12);
n8->neighbors.push_back(n11);
n9->neighbors.push_back(n10);
n9->neighbors.push_back(n11);
n9->neighbors.push_back(n2);
n9->neighbors.push_back(n4);
n9->neighbors.push_back(n6);
n9->neighbors.push_back(n7);
n10->neighbors.push_back(n9);
n10->neighbors.push_back(n11);
n10->neighbors.push_back(n1);
n11->neighbors.push_back(n8);
n11->neighbors.push_back(n12);
n11->neighbors.push_back(n9);
n11->neighbors.push_back(n10);
n12->neighbors.push_back(n8);
// We create the main page that will welcome the user and will ask him what option does he want.
std::cout << "Pick entrance/exit or play defaulft? 0:Default 1:pick" << std::endl;
// Initialize picker to 0.
bool picker = 0;
// Enter choice.
P a g e 10 | 13
std::cin >> picker;
// If chose Default the code follows 12 as exit.
if (!picker) {
n12->exit = true;
// If chose default
bool picker2 = 0;
// Code asks whether user wants it to follow DFS or BFS.
std::cout << "Pick bfs/dfs? 0:dfs 1:bfs" << std::endl;
// Enter choice.
std::cin >> picker2;
// If chose DFs follow DFS function.
if (!picker2) {
g.DFS(n1);
return 0;
}
// Else follow BFS function.
else {
g.BFS(n1);
return 0;
}
}
// If chose pick.
else {
int finish = 12;//by default
int start;
Node* start_pos = n1;
// Ask the user to choose the starting node.
std::cout << "pick the start cell:" << std::endl;
P a g e 11 | 13
// Enter number of node.
std::cin >> start;
// Ask the user to choose the finishing node.
std::cout << "pick the finish cell:" << std::endl;
// Enter number of node.
std::cin >> finish;
for (auto node : g.nodes) {
// The number picked after the question of what node to finish with becomes the exit.
if (node->value == finish) {
node->exit = true;
}
}
for (auto node : g.nodes) {
// The number picked after the question of what node to start with becomes the entrance.
if (node->value == start) {
start_pos = node;
}
}
// What function to follow after choosing the finish and start nodes.
std::cout << "Pick bfs/dfs? 0:dfs 1:bfs" << std::endl;
bool picker3;
// Enter choice.
std::cin >> picker3;
// If chose 0 follow DFS.
if (!picker3) {
g.DFS(start_pos);
}
//Else perform BFS.
else {
P a g e 12 | 13
g.BFS(start_pos);
}
}
}
VII.
Conclusion
In the end after we altered the code many times and solved all the problems that we faced we were
finally able to create a working and successful code that gave us the choice to either perform DFS
or BFS on the normal declared maze where 1 was the entrance and 12 was the exit, in addition, to
performing these codes but with the ability to choose freely any starting and finishing node in the
maze.
P a g e 13 | 13
Download