| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
#include "forward_search.h" |
|---|
| 6 |
#include <qdatetime.h> |
|---|
| 7 |
#include <set> |
|---|
| 8 |
using std::set; |
|---|
| 9 |
|
|---|
| 10 |
list<PlanNode *> matching_nodes; |
|---|
| 11 |
World* buildWorld(PlanNode *n); |
|---|
| 12 |
bool npcEqual(NPC *n1, NPC *n2); |
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
bool forward_search(int time_ms) |
|---|
| 16 |
{ |
|---|
| 17 |
QTime t; |
|---|
| 18 |
t.start(); |
|---|
| 19 |
|
|---|
| 20 |
matching_nodes.clear(); |
|---|
| 21 |
return forward_search_rec(forward_root, time_ms, &t); |
|---|
| 22 |
} |
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
bool forward_search_rec(PlanNode *n, int time_ms, class QTime *t) |
|---|
| 26 |
{ |
|---|
| 27 |
bool match = false; |
|---|
| 28 |
list<Operator>* ops; |
|---|
| 29 |
std::list<Operator>::iterator It; |
|---|
| 30 |
|
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 |
if (!n) { |
|---|
| 34 |
Operator op; |
|---|
| 35 |
op.code = OP_NOOP; |
|---|
| 36 |
forward_root = n = new PlanNode(op, 0); |
|---|
| 37 |
} |
|---|
| 38 |
|
|---|
| 39 |
World *w = buildWorld(n); |
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 |
|
|---|
| 48 |
|
|---|
| 49 |
if (n->isLeaf()) |
|---|
| 50 |
{ |
|---|
| 51 |
ops = GetGregOperators(w); |
|---|
| 52 |
for (It = ops->begin(); It != ops->end(); It++) { |
|---|
| 53 |
PlanNode *new_node = new PlanNode(*It, n->depth + 1); |
|---|
| 54 |
new_node->icon->ul_x = n->icon->ul_x + ICON_W + 200; |
|---|
| 55 |
new_node->icon->ul_y = n->icon->ul_y + (20*ICON_H*(rand()/(double)RAND_MAX) - (10*ICON_H)); |
|---|
| 56 |
n->branches.push_back(new_node); |
|---|
| 57 |
} |
|---|
| 58 |
} |
|---|
| 59 |
else |
|---|
| 60 |
{ |
|---|
| 61 |
std::vector<PlanNode*>::iterator It1; |
|---|
| 62 |
for (It1 = n->branches.begin(); It1 != n->branches.end(); It1++) |
|---|
| 63 |
forward_search_rec(*It1, time_ms, t); |
|---|
| 64 |
} |
|---|
| 65 |
|
|---|
| 66 |
|
|---|
| 67 |
|
|---|
| 68 |
return match; |
|---|
| 69 |
} |
|---|
| 70 |
|
|---|
| 71 |
|
|---|
| 72 |
bool matches_reverse(PlanNode *node, PlanNode *root) |
|---|
| 73 |
{ |
|---|
| 74 |
bool match = false; |
|---|
| 75 |
PlanNode *n; |
|---|
| 76 |
std::vector<PlanNode *>::iterator It; |
|---|
| 77 |
set<PlanNode *> visited; |
|---|
| 78 |
list<PlanNode *> queue; |
|---|
| 79 |
queue.push_back(root); |
|---|
| 80 |
|
|---|
| 81 |
while (!queue.empty()) |
|---|
| 82 |
{ |
|---|
| 83 |
n = queue.front(); queue.pop_front(); |
|---|
| 84 |
|
|---|
| 85 |
if (n && visited.find(n) == visited.end()) |
|---|
| 86 |
{ |
|---|
| 87 |
visited.insert(n); |
|---|
| 88 |
|
|---|
| 89 |
|
|---|
| 90 |
|
|---|
| 91 |
|
|---|
| 92 |
|
|---|
| 93 |
|
|---|
| 94 |
|
|---|
| 95 |
|
|---|
| 96 |
for (It = n->branches.begin(); It != n->branches.end(); It++) |
|---|
| 97 |
queue.push_back(*It); |
|---|
| 98 |
for (It = n->prevs.begin(); It != n->prevs.end(); It++) |
|---|
| 99 |
queue.push_back(*It); |
|---|
| 100 |
} |
|---|
| 101 |
} |
|---|
| 102 |
|
|---|
| 103 |
return match; |
|---|
| 104 |
} |
|---|
| 105 |
|
|---|
| 106 |
|
|---|
| 107 |
World* buildWorld(PlanNode *n) |
|---|
| 108 |
{ |
|---|
| 109 |
|
|---|
| 110 |
World * w = new World(); |
|---|
| 111 |
std::vector<NPC>::iterator It1; |
|---|
| 112 |
for (It1 = real_world->NPCs.begin(); It1 != real_world->NPCs.end(); It1++) |
|---|
| 113 |
w->NPCs.push_back(*It1); |
|---|
| 114 |
std::vector<Item>::iterator It2; |
|---|
| 115 |
for (It2 = real_world->Items.begin(); It2 != real_world->Items.end(); It2++) |
|---|
| 116 |
w->Items.push_back(*It2); |
|---|
| 117 |
std::vector<Location>::iterator It3; |
|---|
| 118 |
for (It3 = real_world->Locations.begin(); It3 != real_world->Locations.end(); It3++) |
|---|
| 119 |
w->Locations.push_back(*It3); |
|---|
| 120 |
w->map_height = real_world->map_height; |
|---|
| 121 |
w->map_width = real_world->map_width; |
|---|
| 122 |
|
|---|
| 123 |
if (!n) return w; |
|---|
| 124 |
|
|---|
| 125 |
|
|---|
| 126 |
|
|---|
| 127 |
Operator *o; |
|---|
| 128 |
list<Operator*> path; |
|---|
| 129 |
PlanNode *node = n; |
|---|
| 130 |
while (node) { |
|---|
| 131 |
path.push_back(&(n->Op)); |
|---|
| 132 |
if (node->prevs.size() > 0) |
|---|
| 133 |
node = node->prevs[0]; |
|---|
| 134 |
else node = NULL; |
|---|
| 135 |
} |
|---|
| 136 |
|
|---|
| 137 |
|
|---|
| 138 |
while (path.size() > 0) |
|---|
| 139 |
{ |
|---|
| 140 |
o = path.front(); path.pop_front(); |
|---|
| 141 |
|
|---|
| 142 |
|
|---|
| 143 |
DoOps(w, o); |
|---|
| 144 |
} |
|---|
| 145 |
|
|---|
| 146 |
return w; |
|---|
| 147 |
} |
|---|
| 148 |
|
|---|
| 149 |
|
|---|
| 150 |
bool worldEqual(World *w1, World *w2) |
|---|
| 151 |
{ |
|---|
| 152 |
if (w1->map_height != w2->map_height) return false; |
|---|
| 153 |
if (w1->map_width != w2->map_width) return false; |
|---|
| 154 |
|
|---|
| 155 |
std::vector<GameObject>::iterator It1, It2; |
|---|
| 156 |
for (It1 = w1->NPCs.begin(), It2 = w2->NPCs.begin(); |
|---|
| 157 |
It1 != w1->NPCs.end(), It2 != w2->NPCs.end(); It1++, It2++) |
|---|
| 158 |
if (!npcEqual((NPC*)It1, (NPC*)It2)) return false; |
|---|
| 159 |
|
|---|
| 160 |
|
|---|
| 161 |
|
|---|
| 162 |
|
|---|
| 163 |
return true; |
|---|
| 164 |
} |
|---|
| 165 |
|
|---|
| 166 |
|
|---|
| 167 |
bool npcEqual(NPC *n1, NPC *n2) |
|---|
| 168 |
{ |
|---|
| 169 |
if (n1->name != n2->name) return false; |
|---|
| 170 |
if (n1->xcoord = n2->xcoord) return false; |
|---|
| 171 |
if (n1->ycoord = n2->ycoord) return false; |
|---|
| 172 |
|
|---|
| 173 |
std::map<string,int>::iterator It1, It2; |
|---|
| 174 |
for (It1 = n1->attributes.begin(), It2 = n2->attributes.begin(); |
|---|
| 175 |
It1 != n1->attributes.end(), It2 != n2->attributes.end(); |
|---|
| 176 |
It1++, It2++) |
|---|
| 177 |
if (*It1 != *It2) return false; |
|---|
| 178 |
|
|---|
| 179 |
std::map<std::pair<string,int>, int>::iterator It3, It4; |
|---|
| 180 |
for (It3 = n1->relationships.begin(), It4 = n2->relationships.begin(); |
|---|
| 181 |
It3 != n1->relationships.end(), It4 != n2->relationships.end(); |
|---|
| 182 |
It3++, It4++) |
|---|
| 183 |
if (*It1 != *It2) return false; |
|---|
| 184 |
|
|---|
| 185 |
return true; |
|---|
| 186 |
} |
|---|
| 187 |
|
|---|
| 188 |
|
|---|
| 189 |
list<std::pair<std::pair<World*,PlanNode*>, Condition> > |
|---|
| 190 |
GetWorldStates(Condition &c) |
|---|
| 191 |
{ |
|---|
| 192 |
World *w; |
|---|
| 193 |
list<std::pair<std::pair<World*,PlanNode*>, Condition> > l; |
|---|
| 194 |
|
|---|
| 195 |
PlanNode *n; |
|---|
| 196 |
std::vector<PlanNode *>::iterator It; |
|---|
| 197 |
set<PlanNode *> visited; |
|---|
| 198 |
list<PlanNode *> queue; |
|---|
| 199 |
queue.push_back(forward_root); |
|---|
| 200 |
|
|---|
| 201 |
while (!queue.empty()) |
|---|
| 202 |
{ |
|---|
| 203 |
n = queue.front(); queue.pop_front(); |
|---|
| 204 |
|
|---|
| 205 |
if (n && visited.find(n) == visited.end()) |
|---|
| 206 |
{ |
|---|
| 207 |
visited.insert(n); |
|---|
| 208 |
|
|---|
| 209 |
if (n->isLeaf()) { |
|---|
| 210 |
w = buildWorld(n); |
|---|
| 211 |
Condition cond = CheckWorldState(w, c); |
|---|
| 212 |
l.push_back(std::pair<std::pair<World*,PlanNode*>, Condition>( |
|---|
| 213 |
std::pair<World*,PlanNode*>(w,n), cond)); |
|---|
| 214 |
} |
|---|
| 215 |
|
|---|
| 216 |
|
|---|
| 217 |
for (It = n->branches.begin(); It != n->branches.end(); It++) |
|---|
| 218 |
queue.push_back(*It); |
|---|
| 219 |
for (It = n->prevs.begin(); It != n->prevs.end(); It++) |
|---|
| 220 |
queue.push_back(*It); |
|---|
| 221 |
} |
|---|
| 222 |
} |
|---|
| 223 |
|
|---|
| 224 |
return l; |
|---|
| 225 |
} |
|---|