-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAstar.cpp
165 lines (141 loc) · 3.52 KB
/
Astar.cpp
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include "Sokoban.h"
/***
* Make sure to update box locations before hand, as it will take the current box locations
* - will assign an h-value to the Stage passed in
*/
void Sokoban::ManhattanDistance(Stage& current)
{
//current.SetH(0);
int temp = 0;
GetBoxes(current);
GetRobot(current);
list<BoxLoc>::iterator bitr;
list<StorageLoc>::iterator sitr;
sitr = listOfStorageLoc.begin();
for (bitr = listOfBoxesLoc.begin(); bitr != listOfBoxesLoc.end(); bitr++)
{
if (sitr != listOfStorageLoc.end())
{
temp += abs(bitr->row - sitr->row - locationOfRobot.row) + abs(bitr->col - sitr->col - locationOfRobot.col);
sitr++;
}
else
{
sitr = listOfStorageLoc.begin();
}
}
current.h = temp;
//std::cerr << "Final h_value: " << current.h << endl;
}
/***
* Will change the rhs to be the Stage with the least f value
* - will also delete that stage from the list that was provided
*/
void Sokoban::FindLeastF(list<Stage>& openList, Stage& temp)
{
list<Stage>::iterator itr = openList.begin();
//Stage temp;
CopyStages(temp, *itr);
//temp.f = 100;
for (itr = openList.begin(); itr != openList.end(); itr++)
{
//std::cerr << "Value: " << itr->f << endl;
if (temp.f > itr->f)
{
CopyStages(temp, *itr);
//Display(temp);
//std::cerr << temp.f << endl;
}
}
//std::cerr << "Final Value: " << temp.f << endl;
for (itr = openList.begin(); itr != openList.end(); itr++)
{
if (CompareStages(temp, *itr))
{
//std::cerr << "Hit" << endl;
itr = openList.erase(itr);
return;
}
}
}
bool Sokoban::AStar(Stage& current, list<Stage>& closedList)
{
time(&begin);
std::list<Stage> openList;
std::list<Stage> succList;
Stage temp(current);
int counter = 0;
closedList.push_back(current);
GetRobot(current);
do
{
if (!MoveRight(current).isDead)
{
succList.push_back(MoveRight(current));
}
if (!MoveUp(current).isDead)
{
succList.push_back(MoveUp(current));
}
if (!MoveLeft(current).isDead)
{
succList.push_back(MoveLeft(current));
}
if (!MoveDown(current).isDead)
{
succList.push_back(MoveDown(current));
}
for (list<Stage>::iterator itr = succList.begin(); itr != succList.end(); itr++)
{
// assign current stage a h-value
GetBoxes(*itr);
ManhattanDistance(*itr);
//itr->g = current.g + 1;
itr->g = 0;
itr->f = itr->g + itr->h;
//std::cerr << itr->f << endl;
}
while (!succList.empty())
{
openList.push_back(succList.front());
succList.pop_front();
}
//Display(current);
//cout << queueStages.size() << endl;
if (openList.size() != 0)
{
FindLeastF(openList, current);
//CopyStages(current, openList.front());
//openList.pop_front();
while (CompareStages(current, closedList) && openList.size() != 0)
{
FindLeastF(openList, current);
//CopyStages(current, openList.front());
//openList.pop_front();
PutSBack(current);
//Display(current);
}
PutSBack(current);
closedList.push_back(current);
GetRobot(current);
}
else
{
cout << "A* search could not find a solution. Exiting now..." << endl;
return false;
}
counter++;
} while (!CheckIfEnd(current));
time(&end);
cout << "A* has found a solution. Outputting to AStar_Output.txt now..." << endl;
OutputList(closedList, "AStar");
while (!openList.empty())
{
openList.pop_front();
}
while (!closedList.empty())
{
closedList.pop_front();
}
return true;
}