7 public boolean m_death;
8 public boolean m_success;
10 public int m_direction; // 0:still, 1:up, 2:down, 3:left, 4:right
17 public int m_leftLives;
18 public int m_leftLevels;
21 public Pacman(int x, int y, Map map) {
22 this.m_oriLocX = this.m_locX = x;
23 this.m_oriLocY = this.m_locY = y;
24 this.m_dx = this.m_dy = 0;
26 this.m_success = false;
28 this.m_tx = this.m_ty = -1;
31 this.m_leftLevels = 0;
35 public void setTarget(int x, int y) {
42 this.m_locX = this.m_oriLocX;
43 this.m_locY = this.m_oriLocY;
45 } else if(this.m_success) {
46 this.m_locX = this.m_oriLocX;
47 this.m_locY = this.m_oriLocY;
48 this.m_success = false;
52 public boolean isFinish() {
54 return this.m_leftLives == 0;
55 } else if(this.m_success) {
56 return this.m_leftLevels == 0;
60 public void tryMove() {
63 // find the shortest possible way to the chosen target
67 private void setNextDirection() {
68 // current position of the ghost
69 int start = this.m_locY * this.m_map.m_nrofblocks + this.m_locX;
71 // get target's position
72 int targetx = this.m_tx;
73 int targety = this.m_ty;
74 int[] nextLocation = new int[2];
75 nextLocation[0] = nextLocation[1] = -1;
78 int end = targety * this.m_map.m_nrofblocks + targetx;
80 // breadth-first traverse the graph view of the maze
81 // check the shortest path for the start node to the end node
83 Vector cuts = new Vector();
89 int parents[] = new int[this.m_map.m_nrofblocks * this.m_map.m_nrofblocks + 1];
90 for(int i = 0; i < parents.length; i++) {
93 if(!BFS(start, end, parents, cuts)) {
96 this.m_map.m_ghostdirections[this.m_index] = this.m_direction = tmpdirection;
98 //System.printString("Use first choice: (" + this.m_dx + ", " + this.m_dy + ")\n");
100 // Reversely go over the parents array to find the next node to reach
101 boolean found = false;
104 int parent = parents[index];
105 if(parent == start) {
112 // set the chase direction
113 int nx = index % this.m_map.m_nrofblocks;
114 int ny = index / this.m_map.m_nrofblocks;
115 this.m_dx = nx - this.m_locX;
116 this.m_dy = ny - this.m_locY;
119 this.m_direction = 4;
120 } else if(this.m_dx < 0) {
122 this.m_direction = 3;
123 } else if(this.m_dy > 0) {
125 this.m_direction = 2;
126 } else if(this.m_dy < 0) {
128 this.m_direction = 1;
131 this.m_direction = 0;
136 tmpdirection = this.m_direction;
138 //System.printString("First choice: (" + tmpdx + ", " + tmpdy + ")\n");
141 // check if this choice follows some other ghosts' path
143 this.m_map.m_directions[this.m_index] = this.m_direction;
146 cuts.addElement(new Integer(index));
147 /*for( int h = 0; h < cuts.size(); h++) {
148 System.printString(cuts.elementAt(h) + ", ");
150 System.printString("\n");*/
156 // This methos do BFS from start node to end node
157 // If there is a path from start to end, return true; otherwise, return false
158 // Array parents records parent for a node in the BFS search,
159 // the last item of parents records the least steps to reach end node from start node
160 // Vector cuts specifies which nodes can not be the first one to access in this BFS
161 private boolean BFS(int start, int end, int[] parents, Vector cuts) {
163 Vector toaccess = new Vector();
164 toaccess.addElement(new Integer(start));
165 while(toaccess.size() > 0) {
166 // pull out the first one to access
167 int access = ((Integer)toaccess.elementAt(0)).intValue();
168 toaccess.removeElementAt(0);
171 parents[parents.length - 1] = steps;
175 Vector neighbours = this.m_map.getNeighbours(access);
176 for(int i = 0; i < neighbours.size(); i++) {
177 int neighbour = ((Integer)neighbours.elementAt(i)).intValue();
178 if(parents[neighbour] == -1) {
180 boolean ignore = false;
181 if(access == start) {
182 // start node, check if the neighbour node is in cuts
184 while((!ignore) && (j < cuts.size())) {
185 int tmp = ((Integer)cuts.elementAt(j)).intValue();
186 if(tmp == neighbour) {
193 parents[neighbour] = access;
194 toaccess.addElement(new Integer(neighbour));
199 parents[parents.length - 1] = -1;
203 // This method returns true if this pacmen can flee in this direction.
204 private boolean canFlee () {
206 int locX = this.m_locX;
207 int locY = this.m_locY;
208 int[] point = new int[2];
209 point[0] = point[1] = -1;
211 // Start off by advancing one in direction for specified location
212 if (this.m_direction == 1) {
215 } else if (this.m_direction == 2) {
218 } else if (this.m_direction == 3) {
221 } else if (this.m_direction == 4) {
228 // Determine next turning location.
230 if (this.m_direction == 1 || this.m_direction == 2) {
232 if (((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) == 0) || // right
233 ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) == 0) || // left
234 ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) != 0) || // up
235 ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) != 0)) { // down
240 if (this.m_direction == 1) {
241 // Check for Top Warp
244 point[1] = this.m_map.m_nrofblocks - 1;
251 // Check for Bottom Warp
252 if (locY == this.m_map.m_nrofblocks - 1) {
264 if (((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) == 0) || // up
265 ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) == 0) || // down
266 ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) != 0) || // right
267 ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) != 0)) { // left
272 if (this.m_direction == 3) {
273 // Check for Left Warp
275 point[0] = this.m_map.m_nrofblocks - 1;
283 // Check for Right Warp
284 if (locX == this.m_map.m_nrofblocks - 1) {
297 // check the least steps for the ghosts to reach point location
299 int end = point[1] * this.m_map.m_nrofblocks + point[0];
300 for(int i = 0; i < this.m_map.m_ghostsX.length; i++) {
301 int start = this.m_map.m_ghostsY[i] * this.m_map.m_nrofblocks + this.m_map.m_ghostsX[i];
302 int parents[] = new int[this.m_map.m_nrofblocks * this.m_map.m_nrofblocks + 1];
303 for(int j = 0; j < parents.length; j++) {
306 if(BFS(start, end, parents, new Vector())) {
307 if((chasesteps == -1) ||
308 (chasesteps > parents[parents.length - 1])) {
309 chasesteps = parents[parents.length - 1];
314 return ((chasesteps == -1) || (steps < chasesteps));
317 // This method will take the specified location and direction and determine
318 // for the given location if the thing moved in that direction, what the
319 // next possible turning location would be.
320 private boolean getDestination (int direction, int locX, int locY, int[] point) {
321 // If the request direction is blocked by a wall, then just return the current location
322 if (((direction == 1) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) != 0)) || // up
323 ((direction == 3) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) != 0)) || // left
324 ((direction == 2) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) != 0)) || // down
325 ((direction == 4) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) != 0))) { // right
331 // Start off by advancing one in direction for specified location
332 if (direction == 1) {
335 } else if (direction == 2) {
338 } else if (direction == 3) {
341 } else if (direction == 4) {
346 // If we violate the grid boundary,
347 // then return false.
350 locY == this.m_map.m_nrofblocks ||
351 locX == this.m_map.m_nrofblocks) {
356 // Determine next turning location.
358 if (direction == 1 || direction == 2) {
360 if (((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) == 0) || // right
361 ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) == 0) || // left
362 ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) != 0) || // up
363 ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) != 0)) { // down
368 if (direction == 1) {
369 // Check for Top Warp
372 point[1] = this.m_map.m_nrofblocks - 1;
378 // Check for Bottom Warp
379 if (locY == this.m_map.m_nrofblocks - 1) {
390 if (((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) == 0) || // up
391 ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) == 0) || // down
392 ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) != 0) || // right
393 ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) != 0)) { // left
398 if (direction == 3) {
399 // Check for Left Warp
401 point[0] = this.m_map.m_nrofblocks - 1;
408 // Check for Right Warp
409 if (locX == this.m_map.m_nrofblocks - 1) {
423 public void doMove() {
424 this.m_locX += this.m_dx;
425 this.m_locY += this.m_dy;
428 //System.printString("Pacmen " + this.m_index + ": (" + this.m_locX + ", " + this.m_locY + ")\n");