5ab35fd80255389cf0cd3a615d3ead4bf0a2a3d3
[IRC.git] / Robust / src / Benchmarks / MMG / Java / Ghost.java
1 public class Ghost {\r
2     \r
3     public int m_locX;\r
4     public int m_locY;\r
5     public int m_index;\r
6     public int m_target;\r
7     public int m_direction;  // 0:still, 1:up, 2:down, 3:left, 4:right\r
8     int m_dx;\r
9     int m_dy;\r
10     Map m_map;\r
11     \r
12     public Ghost(int x, int y, Map map) {\r
13         this.m_locX = x;\r
14         this.m_locY = y;\r
15         this.m_dx = this.m_dy = 0;\r
16         this.m_index = -1;\r
17         this.m_target = -1;\r
18         this.m_direction = 0;\r
19         this.m_map = map;\r
20     }\r
21     \r
22     // 0:still, 1:up, 2:down, 3:left, 4:right\r
23     public void tryMove() {\r
24         //System.printString("step 1\n");\r
25         // reset the target\r
26         this.m_target = -1;\r
27         // find the shortest possible way to the chosen target\r
28         setNextDirection();\r
29     }\r
30     \r
31     private void setNextDirection() {\r
32         // current position of the ghost\r
33         Node start = this.m_map.m_mapNodes[this.m_locY * this.m_map.m_nrofblocks + this.m_locX];\r
34         boolean set = false;\r
35         Vector cuts = new Vector();\r
36         int tmptarget = 0;\r
37         int tmpdx = 0;\r
38         int tmpdy = 0;\r
39         int tmpdirection = 0;\r
40         boolean first = true;\r
41         while(!set) {\r
42             int parents[] = new int[this.m_map.m_nrofblocks * this.m_map.m_nrofblocks + 1];\r
43             for(int i = 0; i < parents.length; i++) {\r
44                 parents[i] = -1;\r
45             }\r
46             if(!BFS(start, parents, cuts)) {\r
47                 this.m_target = tmptarget;\r
48                 this.m_dx = tmpdx;\r
49                 this.m_dy = tmpdy;\r
50                 this.m_map.m_ghostdirections[this.m_index] = this.m_direction = tmpdirection;\r
51                 set = true;\r
52                 //System.printString("Use first choice: (" + this.m_dx + ", " + this.m_dy + ")\n");\r
53             } else {\r
54                 // Reversely go over the parents array to find the next node to reach\r
55                 boolean found = false;\r
56                 int index = this.m_map.m_pacMenY[this.m_target] * this.m_map.m_nrofblocks + this.m_map.m_pacMenX[this.m_target];\r
57                 //System.printString("Target: " + this.m_target + "\n");\r
58                 while(!found) {\r
59                     int parent = parents[index];\r
60                     if(parent == start.getIndex()) {\r
61                         found = true;\r
62                     } else {\r
63                         index = parent;\r
64                     }\r
65                 }\r
66 \r
67                 // set the chase direction\r
68                 int nx = this.m_map.m_mapNodes[index].getXLoc();\r
69                 int ny = this.m_map.m_mapNodes[index].getYLoc();\r
70                 this.m_dx = nx - this.m_locX;\r
71                 this.m_dy = ny - this.m_locY;\r
72                 if(this.m_dx > 0) {\r
73                     // right\r
74                     this.m_direction = 4;\r
75                 } else if(this.m_dx < 0) {\r
76                     // left\r
77                     this.m_direction = 3;\r
78                 } else if(this.m_dy > 0) {\r
79                     // down\r
80                     this.m_direction = 2;\r
81                 } else if(this.m_dy < 0) {\r
82                     // up\r
83                     this.m_direction = 1;\r
84                 } else {\r
85                     // still\r
86                     this.m_direction = 0;\r
87                 }\r
88                 if(first) {\r
89                     tmptarget = this.m_target;\r
90                     tmpdx = this.m_dx;\r
91                     tmpdy = this.m_dy;\r
92                     tmpdirection = this.m_direction;\r
93                     first = false;\r
94                     //System.printString("First choice: (" + tmpdx + ", " + tmpdy + ")\n");\r
95                 }\r
96 \r
97                 // check if this choice follows some other ghosts' path\r
98                 if(!isFollowing()) {\r
99                     this.m_map.m_ghostdirections[this.m_index] = this.m_direction;\r
100                     set = true;\r
101                 } else {\r
102                     cuts.addElement(new Integer(index));\r
103                     /*for( int h = 0; h < cuts.size(); h++) {\r
104                         System.printString(cuts.elementAt(h) + ", ");\r
105                     }\r
106                     System.printString("\n");*/\r
107                 }\r
108             }\r
109         }\r
110     }\r
111     \r
112     // This methos do BFS from start node to end node\r
113     // If there is a path from start to end, return true; otherwise, return false\r
114     // Array parents records parent for a node in the BFS search,\r
115     // the last item of parents records the least steps to reach end node from start node\r
116     // Vector cuts specifies which nodes can not be the first one to access in this BFS\r
117 <<<<<<< Ghost.java
118     private boolean BFS(Node start, int[] parents, Vector cuts) {\r
119         //System.printString("aaa\n");\r
120         int steps = 0;\r
121 =======
122     private boolean BFS(Node start, Node end, int[] parents, Vector cuts) {\r
123         int steps = 0;\r
124 >>>>>>> 1.3
125         Vector toaccess = new Vector();\r
126         toaccess.addElement(start);\r
127         while(toaccess.size() > 0) {\r
128             //System.printString("bbb\n");\r
129             // pull out the first one to access\r
130             Node access = (Node)toaccess.elementAt(0);\r
131             toaccess.removeElementAt(0);\r
132 <<<<<<< Ghost.java
133             for(int i = 0; i < this.m_map.m_pacMenX.length; i++) {\r
134                 if((access.getXLoc() == this.m_map.m_pacMenX[i]) && (access.getYLoc() == this.m_map.m_pacMenY[i])) {\r
135                     // hit one pacman\r
136                     this.m_target = i;\r
137                     parents[parents.length - 1] = steps;\r
138                     return true;\r
139                 }\r
140 =======
141             if(access.getIndex() == end.getIndex()) {\r
142                 // hit the end node\r
143                 parents[parents.length - 1] = steps;\r
144                 return true;\r
145 >>>>>>> 1.3
146             }\r
147             steps++;\r
148             Vector neighbours = access.getNeighbours();\r
149             for(int i = 0; i < neighbours.size(); i++) {\r
150                 Node neighbour = (Node)neighbours.elementAt(i);\r
151                 if(parents[neighbour.getIndex()] == -1) {\r
152                     // not accessed\r
153                     boolean ignore = false;\r
154                     if(access.getIndex() == start.getIndex()) {\r
155                         // start node, check if the neighbour node is in cuts\r
156                         int j = 0;\r
157                         while((!ignore) && (j < cuts.size())) {\r
158                             int tmp = ((Integer)cuts.elementAt(j)).intValue();\r
159                             if(tmp == neighbour.getIndex()) {\r
160                                 ignore = true;\r
161                             }\r
162                             j++;\r
163                         }\r
164                     }\r
165                     if(!ignore) {\r
166                         parents[neighbour.getIndex()] = access.getIndex();\r
167                         toaccess.addElement(neighbour);\r
168                     }\r
169                 }\r
170             }\r
171         }\r
172 <<<<<<< Ghost.java
173         //System.printString("ccc\n");\r
174         parents[parents.length - 1] = -1;\r
175 =======
176         parents[parents.length - 1] = -1;\r
177 >>>>>>> 1.3
178         return false;\r
179     }\r
180     \r
181     // This method returns true if this ghost is traveling to the same\r
182     // destination with the same direction as another ghost.\r
183     private boolean isFollowing () {\r
184         boolean bFollowing = false;\r
185         double  dRandom;\r
186 \r
187         // If the ghost is in the same location as another ghost\r
188         // and moving in the same direction, then they are on\r
189         // top of each other and should not follow.\r
190         for (int i = 0; i < this.m_map.m_ghostsX.length; i++) {\r
191             // Ignore myself\r
192             if (this.m_index != i) {\r
193                 if (this.m_map.m_ghostsX[i] == this.m_locX &&\r
194                         this.m_map.m_ghostsY[i] == this.m_locY &&\r
195                         this.m_map.m_ghostdirections[i] == this.m_direction) {\r
196                     return true;\r
197                 }\r
198             }\r
199         }\r
200 \r
201         // This will allow ghosts to often\r
202         // clump together for easier eating\r
203         dRandom = this.m_map.m_r.nextDouble();\r
204         if (dRandom < .90) {  \r
205             //if (m_bInsaneAI && dRandom < .25)\r
206             //   return false;\r
207             //else\r
208             return false;\r
209         }\r
210 \r
211         // If ghost is moving to the same location and using the\r
212         // same direction, then it is following another ghost.      \r
213         for (int i = 0; i < this.m_map.m_ghostsX.length; i++) {        \r
214             // Ignore myself        \r
215             if (this.m_index != i) {\r
216                 if (this.m_map.m_targets[i] == this.m_target &&\r
217                         this.m_map.m_ghostdirections[i] == this.m_direction) {\r
218                     return true;\r
219                 }\r
220             }\r
221         }\r
222 \r
223         return bFollowing;\r
224     }\r
225     \r
226     // This method will take the specified location and direction and determine\r
227     // for the given location if the thing moved in that direction, what the\r
228     // next possible turning location would be.\r
229     private boolean getDestination (int direction, int locX, int locY, int[] point) {\r
230        // If the request direction is blocked by a wall, then just return the current location\r
231        if (((direction == 1) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) != 0)) || // up\r
232            ((direction == 3) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) != 0)) ||  // left\r
233            ((direction == 2) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) != 0)) || // down\r
234            ((direction == 4) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) != 0))) { // right \r
235           point[0] = locX;\r
236           point[1] = locY;\r
237           return false;\r
238        }\r
239           \r
240        // Start off by advancing one in direction for specified location\r
241        if (direction == 1) {\r
242            // up\r
243            locY--;\r
244        } else if (direction == 2) {\r
245            // down\r
246            locY++;\r
247        } else if (direction == 3) {\r
248            // left\r
249            locX--;\r
250        } else if (direction == 4) {\r
251            // right\r
252            locX++;\r
253        }\r
254        \r
255        // If we violate the grid boundary,\r
256        // then return false.\r
257        if (locY < 0 ||\r
258            locX < 0 ||\r
259            locY == this.m_map.m_nrofblocks ||\r
260            locX == this.m_map.m_nrofblocks) {\r
261            return false;\r
262        }\r
263        \r
264        boolean set = false;\r
265        // Determine next turning location.\r
266        while (!set) {\r
267           if (direction == 1 || direction == 2) { \r
268               // up or down\r
269               if (((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) == 0) || // right\r
270                       ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) == 0) || // left\r
271                       ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) != 0) || // up\r
272                       ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) != 0))  { // down\r
273                   point[0] = locX;\r
274                   point[1] = locY;\r
275                   set = true;\r
276                } else {\r
277                    if (direction == 1) {\r
278                        // Check for Top Warp\r
279                        if (locY == 0) {\r
280                            point[0] = locX;\r
281                            point[1] = this.m_map.m_nrofblocks - 1;\r
282                            set = true;\r
283                        } else {\r
284                            locY--;\r
285                        }\r
286                    } else {\r
287                        // Check for Bottom Warp\r
288                        if (locY == this.m_map.m_nrofblocks - 1) {\r
289                            point[0] = locX;\r
290                            point[1] = 0;\r
291                            set = true;\r
292                        } else {\r
293                            locY++;\r
294                        }\r
295                    }\r
296                }\r
297           } else {\r
298               // left or right\r
299               if (((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) == 0) || // up\r
300                       ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) == 0) || // down\r
301                       ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) != 0) || // right\r
302                       ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) != 0)) { // left  \r
303                   point[0] = locX;\r
304                   point[1] = locY;\r
305                   set = true;\r
306               } else {\r
307                   if (direction == 3) {\r
308                       // Check for Left Warp\r
309                       if (locX == 0) {\r
310                           point[0] = this.m_map.m_nrofblocks - 1;\r
311                           point[1] = locY;\r
312                           set = true;\r
313                       } else {\r
314                           locX--;\r
315                       }\r
316                   } else {\r
317                       // Check for Right Warp\r
318                       if (locX == this.m_map.m_nrofblocks - 1) {\r
319                           point[0] = 0;\r
320                           point[1] = locY;\r
321                           set = true;\r
322                       } else {\r
323                           locX++;\r
324                       }\r
325                   }\r
326               }\r
327           }\r
328        }\r
329        return true;\r
330     }\r
331     \r
332     public void doMove() {\r
333         this.m_locX += this.m_dx;\r
334         this.m_locY += this.m_dy;\r
335         this.m_dx = 0;\r
336         this.m_dy = 0;\r
337         //System.printString("Ghost " + this.m_index + ": (" + this.m_locX + ", " + this.m_locY + ")\n");\r
338     }\r
339 }