-public class Ghost {\r
- \r
- public int m_locX;\r
- public int m_locY;\r
- public int m_index;\r
- public int m_target;\r
- public int m_direction; // 0:still, 1:up, 2:down, 3:left, 4:right\r
- int m_dx;\r
- int m_dy;\r
- Map m_map;\r
- \r
- public Ghost(int x, int y, Map map) {\r
- this.m_locX = x;\r
- this.m_locY = y;\r
- this.m_dx = this.m_dy = 0;\r
- this.m_index = -1;\r
- this.m_target = -1;\r
- this.m_direction = 0;\r
- this.m_map = map;\r
- }\r
- \r
- // 0:still, 1:up, 2:down, 3:left, 4:right\r
- public void tryMove() {\r
- //System.printString("step 1\n");\r
- // reset the target\r
- this.m_target = -1;\r
- // find the shortest possible way to the chosen target\r
- setNextDirection();\r
- }\r
- \r
- private void setNextDirection() {\r
- // current position of the ghost\r
- Node start = this.m_map.m_mapNodes[this.m_locY * this.m_map.m_nrofblocks + this.m_locX];\r
- boolean set = false;\r
- Vector cuts = new Vector();\r
- int tmptarget = 0;\r
- int tmpdx = 0;\r
- int tmpdy = 0;\r
- int tmpdirection = 0;\r
- boolean first = true;\r
- while(!set) {\r
- int parents[] = new int[this.m_map.m_nrofblocks * this.m_map.m_nrofblocks + 1];\r
- for(int i = 0; i < parents.length; i++) {\r
- parents[i] = -1;\r
- }\r
- if(!BFS(start, parents, cuts)) {\r
- this.m_target = tmptarget;\r
- this.m_dx = tmpdx;\r
- this.m_dy = tmpdy;\r
- this.m_map.m_ghostdirections[this.m_index] = this.m_direction = tmpdirection;\r
- set = true;\r
- //System.printString("Use first choice: (" + this.m_dx + ", " + this.m_dy + ")\n");\r
- } else {\r
- // Reversely go over the parents array to find the next node to reach\r
- boolean found = false;\r
- int index = this.m_map.m_pacMenY[this.m_target] * this.m_map.m_nrofblocks + this.m_map.m_pacMenX[this.m_target];\r
- //System.printString("Target: " + this.m_target + "\n");\r
- while(!found) {\r
- int parent = parents[index];\r
- if(parent == start.getIndex()) {\r
- found = true;\r
- } else {\r
- index = parent;\r
- }\r
- }\r
-\r
- // set the chase direction\r
- int nx = this.m_map.m_mapNodes[index].getXLoc();\r
- int ny = this.m_map.m_mapNodes[index].getYLoc();\r
- this.m_dx = nx - this.m_locX;\r
- this.m_dy = ny - this.m_locY;\r
- if(this.m_dx > 0) {\r
- // right\r
- this.m_direction = 4;\r
- } else if(this.m_dx < 0) {\r
- // left\r
- this.m_direction = 3;\r
- } else if(this.m_dy > 0) {\r
- // down\r
- this.m_direction = 2;\r
- } else if(this.m_dy < 0) {\r
- // up\r
- this.m_direction = 1;\r
- } else {\r
- // still\r
- this.m_direction = 0;\r
- }\r
- if(first) {\r
- tmptarget = this.m_target;\r
- tmpdx = this.m_dx;\r
- tmpdy = this.m_dy;\r
- tmpdirection = this.m_direction;\r
- first = false;\r
- //System.printString("First choice: (" + tmpdx + ", " + tmpdy + ")\n");\r
- }\r
-\r
- // check if this choice follows some other ghosts' path\r
- if(!isFollowing()) {\r
- this.m_map.m_ghostdirections[this.m_index] = this.m_direction;\r
- set = true;\r
- } else {\r
- cuts.addElement(new Integer(index));\r
- /*for( int h = 0; h < cuts.size(); h++) {\r
- System.printString(cuts.elementAt(h) + ", ");\r
- }\r
- System.printString("\n");*/\r
- }\r
- }\r
- }\r
- }\r
- \r
- // This methos do BFS from start node to end node\r
- // If there is a path from start to end, return true; otherwise, return false\r
- // Array parents records parent for a node in the BFS search,\r
- // the last item of parents records the least steps to reach end node from start node\r
- // Vector cuts specifies which nodes can not be the first one to access in this BFS\r
-<<<<<<< Ghost.java
- private boolean BFS(Node start, int[] parents, Vector cuts) {\r
- //System.printString("aaa\n");\r
- int steps = 0;\r
-=======
- private boolean BFS(Node start, Node end, int[] parents, Vector cuts) {\r
- int steps = 0;\r
->>>>>>> 1.3
- Vector toaccess = new Vector();\r
- toaccess.addElement(start);\r
- while(toaccess.size() > 0) {\r
- //System.printString("bbb\n");\r
- // pull out the first one to access\r
- Node access = (Node)toaccess.elementAt(0);\r
- toaccess.removeElementAt(0);\r
-<<<<<<< Ghost.java
- for(int i = 0; i < this.m_map.m_pacMenX.length; i++) {\r
- if((access.getXLoc() == this.m_map.m_pacMenX[i]) && (access.getYLoc() == this.m_map.m_pacMenY[i])) {\r
- // hit one pacman\r
- this.m_target = i;\r
- parents[parents.length - 1] = steps;\r
- return true;\r
- }\r
-=======
- if(access.getIndex() == end.getIndex()) {\r
- // hit the end node\r
- parents[parents.length - 1] = steps;\r
- return true;\r
->>>>>>> 1.3
- }\r
- steps++;\r
- Vector neighbours = access.getNeighbours();\r
- for(int i = 0; i < neighbours.size(); i++) {\r
- Node neighbour = (Node)neighbours.elementAt(i);\r
- if(parents[neighbour.getIndex()] == -1) {\r
- // not accessed\r
- boolean ignore = false;\r
- if(access.getIndex() == start.getIndex()) {\r
- // start node, check if the neighbour node is in cuts\r
- int j = 0;\r
- while((!ignore) && (j < cuts.size())) {\r
- int tmp = ((Integer)cuts.elementAt(j)).intValue();\r
- if(tmp == neighbour.getIndex()) {\r
- ignore = true;\r
- }\r
- j++;\r
- }\r
- }\r
- if(!ignore) {\r
- parents[neighbour.getIndex()] = access.getIndex();\r
- toaccess.addElement(neighbour);\r
- }\r
- }\r
- }\r
- }\r
-<<<<<<< Ghost.java
- //System.printString("ccc\n");\r
- parents[parents.length - 1] = -1;\r
-=======
- parents[parents.length - 1] = -1;\r
->>>>>>> 1.3
- return false;\r
- }\r
- \r
- // This method returns true if this ghost is traveling to the same\r
- // destination with the same direction as another ghost.\r
- private boolean isFollowing () {\r
- boolean bFollowing = false;\r
- double dRandom;\r
-\r
- // If the ghost is in the same location as another ghost\r
- // and moving in the same direction, then they are on\r
- // top of each other and should not follow.\r
- for (int i = 0; i < this.m_map.m_ghostsX.length; i++) {\r
- // Ignore myself\r
- if (this.m_index != i) {\r
- if (this.m_map.m_ghostsX[i] == this.m_locX &&\r
- this.m_map.m_ghostsY[i] == this.m_locY &&\r
- this.m_map.m_ghostdirections[i] == this.m_direction) {\r
- return true;\r
- }\r
- }\r
- }\r
-\r
- // This will allow ghosts to often\r
- // clump together for easier eating\r
- dRandom = this.m_map.m_r.nextDouble();\r
- if (dRandom < .90) { \r
- //if (m_bInsaneAI && dRandom < .25)\r
- // return false;\r
- //else\r
- return false;\r
- }\r
-\r
- // If ghost is moving to the same location and using the\r
- // same direction, then it is following another ghost. \r
- for (int i = 0; i < this.m_map.m_ghostsX.length; i++) { \r
- // Ignore myself \r
- if (this.m_index != i) {\r
- if (this.m_map.m_targets[i] == this.m_target &&\r
- this.m_map.m_ghostdirections[i] == this.m_direction) {\r
- return true;\r
- }\r
- }\r
- }\r
-\r
- return bFollowing;\r
- }\r
- \r
- // This method will take the specified location and direction and determine\r
- // for the given location if the thing moved in that direction, what the\r
- // next possible turning location would be.\r
- private boolean getDestination (int direction, int locX, int locY, int[] point) {\r
- // If the request direction is blocked by a wall, then just return the current location\r
- if (((direction == 1) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) != 0)) || // up\r
- ((direction == 3) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) != 0)) || // left\r
- ((direction == 2) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) != 0)) || // down\r
- ((direction == 4) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) != 0))) { // right \r
- point[0] = locX;\r
- point[1] = locY;\r
- return false;\r
- }\r
- \r
- // Start off by advancing one in direction for specified location\r
- if (direction == 1) {\r
- // up\r
- locY--;\r
- } else if (direction == 2) {\r
- // down\r
- locY++;\r
- } else if (direction == 3) {\r
- // left\r
- locX--;\r
- } else if (direction == 4) {\r
- // right\r
- locX++;\r
- }\r
- \r
- // If we violate the grid boundary,\r
- // then return false.\r
- if (locY < 0 ||\r
- locX < 0 ||\r
- locY == this.m_map.m_nrofblocks ||\r
- locX == this.m_map.m_nrofblocks) {\r
- return false;\r
- }\r
- \r
- boolean set = false;\r
- // Determine next turning location.\r
- while (!set) {\r
- if (direction == 1 || direction == 2) { \r
- // up or down\r
- if (((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) == 0) || // right\r
- ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) == 0) || // left\r
- ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) != 0) || // up\r
- ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) != 0)) { // down\r
- point[0] = locX;\r
- point[1] = locY;\r
- set = true;\r
- } else {\r
- if (direction == 1) {\r
- // Check for Top Warp\r
- if (locY == 0) {\r
- point[0] = locX;\r
- point[1] = this.m_map.m_nrofblocks - 1;\r
- set = true;\r
- } else {\r
- locY--;\r
- }\r
- } else {\r
- // Check for Bottom Warp\r
- if (locY == this.m_map.m_nrofblocks - 1) {\r
- point[0] = locX;\r
- point[1] = 0;\r
- set = true;\r
- } else {\r
- locY++;\r
- }\r
- }\r
- }\r
- } else {\r
- // left or right\r
- if (((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) == 0) || // up\r
- ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) == 0) || // down\r
- ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) != 0) || // right\r
- ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) != 0)) { // left \r
- point[0] = locX;\r
- point[1] = locY;\r
- set = true;\r
- } else {\r
- if (direction == 3) {\r
- // Check for Left Warp\r
- if (locX == 0) {\r
- point[0] = this.m_map.m_nrofblocks - 1;\r
- point[1] = locY;\r
- set = true;\r
- } else {\r
- locX--;\r
- }\r
- } else {\r
- // Check for Right Warp\r
- if (locX == this.m_map.m_nrofblocks - 1) {\r
- point[0] = 0;\r
- point[1] = locY;\r
- set = true;\r
- } else {\r
- locX++;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- return true;\r
- }\r
- \r
- public void doMove() {\r
- this.m_locX += this.m_dx;\r
- this.m_locY += this.m_dy;\r
- this.m_dx = 0;\r
- this.m_dy = 0;\r
- //System.printString("Ghost " + this.m_index + ": (" + this.m_locX + ", " + this.m_locY + ")\n");\r
- }\r
-}
\ No newline at end of file
+public class Ghost {
+
+ public int m_locX;
+ public int m_locY;
+ public int m_index;
+ public int m_target;
+ public int m_direction; // 0:still, 1:up, 2:down, 3:left, 4:right
+ int m_dx;
+ int m_dy;
+ Map m_map;
+
+ public Ghost(int x, int y, Map map) {
+ this.m_locX = x;
+ this.m_locY = y;
+ this.m_dx = this.m_dy = 0;
+ this.m_index = -1;
+ this.m_target = -1;
+ this.m_direction = 0;
+ this.m_map = map;
+ }
+
+ // 0:still, 1:up, 2:down, 3:left, 4:right
+ public void tryMove() {
+ //System.printString("step 1\n");
+ // reset the target
+ this.m_target = -1;
+ // find the shortest possible way to the chosen target
+ setNextDirection();
+ }
+
+ private void setNextDirection() {
+ // current position of the ghost
+ Node start = this.m_map.m_mapNodes[this.m_locY * this.m_map.m_nrofblocks + this.m_locX];
+ boolean set = false;
+ Vector cuts = new Vector();
+ int tmptarget = 0;
+ int tmpdx = 0;
+ int tmpdy = 0;
+ int tmpdirection = 0;
+ boolean first = true;
+ while(!set) {
+ int parents[] = new int[this.m_map.m_nrofblocks * this.m_map.m_nrofblocks + 1];
+ for(int i = 0; i < parents.length; i++) {
+ parents[i] = -1;
+ }
+ if(!BFS(start, parents, cuts)) {
+ this.m_target = tmptarget;
+ this.m_dx = tmpdx;
+ this.m_dy = tmpdy;
+ this.m_map.m_ghostdirections[this.m_index] = this.m_direction = tmpdirection;
+ set = true;
+ //System.printString("Use first choice: (" + this.m_dx + ", " + this.m_dy + ")\n");
+ } else {
+ // Reversely go over the parents array to find the next node to reach
+ boolean found = false;
+ int index = this.m_map.m_pacMenY[this.m_target] * this.m_map.m_nrofblocks + this.m_map.m_pacMenX[this.m_target];
+ //System.printString("Target: " + this.m_target + "\n");
+ while(!found) {
+ int parent = parents[index];
+ if(parent == start.getIndex()) {
+ found = true;
+ } else {
+ index = parent;
+ }
+ }
+
+ // set the chase direction
+ int nx = this.m_map.m_mapNodes[index].getXLoc();
+ int ny = this.m_map.m_mapNodes[index].getYLoc();
+ this.m_dx = nx - this.m_locX;
+ this.m_dy = ny - this.m_locY;
+ if(this.m_dx > 0) {
+ // right
+ this.m_direction = 4;
+ } else if(this.m_dx < 0) {
+ // left
+ this.m_direction = 3;
+ } else if(this.m_dy > 0) {
+ // down
+ this.m_direction = 2;
+ } else if(this.m_dy < 0) {
+ // up
+ this.m_direction = 1;
+ } else {
+ // still
+ this.m_direction = 0;
+ }
+ if(first) {
+ tmptarget = this.m_target;
+ tmpdx = this.m_dx;
+ tmpdy = this.m_dy;
+ tmpdirection = this.m_direction;
+ first = false;
+ //System.printString("First choice: (" + tmpdx + ", " + tmpdy + ")\n");
+ }
+
+ // check if this choice follows some other ghosts' path
+ if(!isFollowing()) {
+ this.m_map.m_ghostdirections[this.m_index] = this.m_direction;
+ set = true;
+ } else {
+ cuts.addElement(new Integer(index));
+ /*for( int h = 0; h < cuts.size(); h++) {
+ System.printString(cuts.elementAt(h) + ", ");
+ }
+ System.printString("\n");*/
+ }
+ }
+ }
+ }
+
+ // This methos do BFS from start node to end node
+ // If there is a path from start to end, return true; otherwise, return false
+ // Array parents records parent for a node in the BFS search,
+ // the last item of parents records the least steps to reach end node from start node
+ // Vector cuts specifies which nodes can not be the first one to access in this BFS
+ private boolean BFS(Node start, int[] parents, Vector cuts) {
+ int steps = 0;
+ Vector toaccess = new Vector();
+ toaccess.addElement(start);
+ while(toaccess.size() > 0) {
+ //System.printString("bbb\n");
+ // pull out the first one to access
+ Node access = (Node)toaccess.elementAt(0);
+ toaccess.removeElementAt(0);
+ for(int i = 0; i < this.m_map.m_pacMenX.length; i++) {
+ if((access.getXLoc() == this.m_map.m_pacMenX[i]) && (access.getYLoc() == this.m_map.m_pacMenY[i])) {
+ // hit one pacman
+ this.m_target = i;
+ parents[parents.length - 1] = steps;
+ return true;
+ }
+ }
+ steps++;
+ Vector neighbours = access.getNeighbours();
+ for(int i = 0; i < neighbours.size(); i++) {
+ Node neighbour = (Node)neighbours.elementAt(i);
+ if(parents[neighbour.getIndex()] == -1) {
+ // not accessed
+ boolean ignore = false;
+ if(access.getIndex() == start.getIndex()) {
+ // start node, check if the neighbour node is in cuts
+ int j = 0;
+ while((!ignore) && (j < cuts.size())) {
+ int tmp = ((Integer)cuts.elementAt(j)).intValue();
+ if(tmp == neighbour.getIndex()) {
+ ignore = true;
+ }
+ j++;
+ }
+ }
+ if(!ignore) {
+ parents[neighbour.getIndex()] = access.getIndex();
+ toaccess.addElement(neighbour);
+ }
+ }
+ }
+ }
+ parents[parents.length - 1] = -1;
+ return false;
+ }
+
+ // This method returns true if this ghost is traveling to the same
+ // destination with the same direction as another ghost.
+ private boolean isFollowing () {
+ boolean bFollowing = false;
+ double dRandom;
+
+ // If the ghost is in the same location as another ghost
+ // and moving in the same direction, then they are on
+ // top of each other and should not follow.
+ for (int i = 0; i < this.m_map.m_ghostsX.length; i++) {
+ // Ignore myself
+ if (this.m_index != i) {
+ if (this.m_map.m_ghostsX[i] == this.m_locX &&
+ this.m_map.m_ghostsY[i] == this.m_locY &&
+ this.m_map.m_ghostdirections[i] == this.m_direction) {
+ return true;
+ }
+ }
+ }
+
+ // This will allow ghosts to often
+ // clump together for easier eating
+ dRandom = this.m_map.m_r.nextDouble();
+ if (dRandom < .90) {
+ //if (m_bInsaneAI && dRandom < .25)
+ // return false;
+ //else
+ return false;
+ }
+
+ // If ghost is moving to the same location and using the
+ // same direction, then it is following another ghost.
+ for (int i = 0; i < this.m_map.m_ghostsX.length; i++) {
+ // Ignore myself
+ if (this.m_index != i) {
+ if (this.m_map.m_targets[i] == this.m_target &&
+ this.m_map.m_ghostdirections[i] == this.m_direction) {
+ return true;
+ }
+ }
+ }
+
+ return bFollowing;
+ }
+
+ // This method will take the specified location and direction and determine
+ // for the given location if the thing moved in that direction, what the
+ // next possible turning location would be.
+ private boolean getDestination (int direction, int locX, int locY, int[] point) {
+ // If the request direction is blocked by a wall, then just return the current location
+ if (((direction == 1) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) != 0)) || // up
+ ((direction == 3) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) != 0)) || // left
+ ((direction == 2) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) != 0)) || // down
+ ((direction == 4) && ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) != 0))) { // right
+ point[0] = locX;
+ point[1] = locY;
+ return false;
+ }
+
+ // Start off by advancing one in direction for specified location
+ if (direction == 1) {
+ // up
+ locY--;
+ } else if (direction == 2) {
+ // down
+ locY++;
+ } else if (direction == 3) {
+ // left
+ locX--;
+ } else if (direction == 4) {
+ // right
+ locX++;
+ }
+
+ // If we violate the grid boundary,
+ // then return false.
+ if (locY < 0 ||
+ locX < 0 ||
+ locY == this.m_map.m_nrofblocks ||
+ locX == this.m_map.m_nrofblocks) {
+ return false;
+ }
+
+ boolean set = false;
+ // Determine next turning location.
+ while (!set) {
+ if (direction == 1 || direction == 2) {
+ // up or down
+ if (((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) == 0) || // right
+ ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) == 0) || // left
+ ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) != 0) || // up
+ ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) != 0)) { // down
+ point[0] = locX;
+ point[1] = locY;
+ set = true;
+ } else {
+ if (direction == 1) {
+ // Check for Top Warp
+ if (locY == 0) {
+ point[0] = locX;
+ point[1] = this.m_map.m_nrofblocks - 1;
+ set = true;
+ } else {
+ locY--;
+ }
+ } else {
+ // Check for Bottom Warp
+ if (locY == this.m_map.m_nrofblocks - 1) {
+ point[0] = locX;
+ point[1] = 0;
+ set = true;
+ } else {
+ locY++;
+ }
+ }
+ }
+ } else {
+ // left or right
+ if (((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 2) == 0) || // up
+ ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 8) == 0) || // down
+ ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 4) != 0) || // right
+ ((int)(this.m_map.m_map[locX + locY * this.m_map.m_nrofblocks] & 1) != 0)) { // left
+ point[0] = locX;
+ point[1] = locY;
+ set = true;
+ } else {
+ if (direction == 3) {
+ // Check for Left Warp
+ if (locX == 0) {
+ point[0] = this.m_map.m_nrofblocks - 1;
+ point[1] = locY;
+ set = true;
+ } else {
+ locX--;
+ }
+ } else {
+ // Check for Right Warp
+ if (locX == this.m_map.m_nrofblocks - 1) {
+ point[0] = 0;
+ point[1] = locY;
+ set = true;
+ } else {
+ locX++;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ public void doMove() {
+ this.m_locX += this.m_dx;
+ this.m_locY += this.m_dy;
+ this.m_dx = 0;
+ this.m_dy = 0;
+ //System.printString("Ghost " + this.m_index + ": (" + this.m_locX + ", " + this.m_locY + ")\n");
+ }
+}