root/deus/forward_search.cpp

Revision 8, 5.3 kB (checked in by pantley2, 4 years ago)

added old DEUS project to SVN

Line 
1 /**
2  * forward_search.cpp
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         //if (t->elapsed() > time_ms) return false;
31
32         // This must be the new root!
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         // See if this state is a match!
42         /* Steve ruined all my fun.
43         std::vector<PlanNode *>::iterator It1;
44         for (It1 = regression_roots.begin(); It1 != regression_roots.end(); It1++)
45                 match |= matches_reverse(n, *It1);
46         */
47
48         // Only expand leaves
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         // Look at children, here, if you want to
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                         // if world state matches
90                         //if (n...) {
91                         //      matching_nodes.push_back(n);
92                         //      match = true
93                         //}
94
95                         // Parents and children
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         // Copy the world
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         // Find path to real world
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];  // all paths lead to rome
134                 else node = NULL;
135         }
136
137         // Rebuild the world
138         while (path.size() > 0)
139         {
140                 o = path.front(); path.pop_front();
141
142                 // apply operator to fake world
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         // HACK: No items...
161         // HACK: Locations will never change...
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                         // Parents and children
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 }
Note: See TracBrowser for help on using the browser.