-
Notifications
You must be signed in to change notification settings - Fork 0
/
BFS.h
139 lines (117 loc) · 4.16 KB
/
BFS.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//
// Created by eizzker on 21/01/2020.
//
#ifndef MILE_STONE_2_BFS_H
#define MILE_STONE_2_BFS_H
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <queue>
#include "Searcher.h"
#include "Searchable.h"
template<class T, class Q, class P>
class BFS : public Searcher<T, Q, P> {
private:
string shortestPath = "";
public:
int decideWhereICameFrom(State<P> *state) {/*return the direction we move from parent : 0-initial state,
* 1-move to the left
* 2-move to the right
* 3-move down
* 4-move up*/
if (state->getCameFrom() == nullptr) {
return 0;
}
if (state->getState()->getRow() == state->getCameFrom()->getState()->getRow()) {
if (state->getState()->getCol() > state->getCameFrom()->getState()->getCol()) {
return 2;
} else {
return 1;
}
} else {
if (state->getState()->getRow() > state->getCameFrom()->getState()->getRow()) {
return 3;
} else {
return 4;
}
}
}
void WriteDirection(int decideDirection, int totalCost) {
string extra;
switch (decideDirection) {
case 1:
extra = "Left (" + to_string(totalCost) + ")";
this->shortestPath = extra + this->shortestPath;
break;
case 2 :
extra = "Right (" + to_string(totalCost) + ")";
this->shortestPath = extra + this->shortestPath;
break;
case 3 :
extra = "Down (" + to_string(totalCost) + ")";
this->shortestPath = extra + this->shortestPath;
break;
case 4 :
extra = "Up (" + to_string(totalCost) + ")";
this->shortestPath = extra + this->shortestPath;
break;
default:
break;
}
}
void makePath(Searcheable<T, P> *searchable) {
State<P> *curr = searchable->getGoalState();
// first print of direcion
int diraction = decideWhereICameFrom(curr);
WriteDirection(diraction, curr->gettotalCost());
curr = curr->getCameFrom();
// all the rest direction prints.
while (curr->getCameFrom() != nullptr) {
this->shortestPath = ", " + this->shortestPath;
diraction = decideWhereICameFrom(curr);
if (curr->getCameFrom() == nullptr) {
WriteDirection(diraction, curr->getCost());
} else {
WriteDirection(diraction, curr->gettotalCost());
}
curr = curr->getCameFrom();
}
}
Q search(Searcheable<T, P> *searchable) {
// Mark the source cell as visited
searchable->getInitialState()->set_visited();
// Create a queue for BFS
queue < State<P> * > q;
q.push(searchable->getInitialState()); // Enqueue source cell
// Do a BFS starting from source cell
while (!q.empty()) {
State<P> *curr = q.front();
Point *pt = curr->getState();
// If we have reached the destination cell,
// we are done
if (pt->getRow() == searchable->getGoalState()->getState()->getRow()
&& pt->getCol() == searchable->getGoalState()->getState()->getCol()) {
int total = curr->gettotalCost(); // need to b changed to string of path;
makePath(searchable);
return this->shortestPath;
}
// Otherwise dequeue the front cell in the queue
// and enqueue its adjacent cells
q.pop();
vector<State<P> *> adj = searchable->getAllPossibleStates(curr);
int i = 0;
int size = adj.size();
for (i = 0; i < size; i++) {
if (adj[i]->getVisited() == 0) {
adj[i]->set_visited();
adj[i]->setCameFrom(curr);
q.push(adj[i]);
}
}
}
// Return -1 if destination cannot be reached
throw "could not find path";
}
};
#endif //MILE_STONE_2_BFS_H