changes
authorjzhou <jzhou>
Wed, 3 Sep 2008 03:47:37 +0000 (03:47 +0000)
committerjzhou <jzhou>
Wed, 3 Sep 2008 03:47:37 +0000 (03:47 +0000)
Robust/src/Benchmarks/MMG/Java/Ghost.java
Robust/src/Benchmarks/MMG/Java/MMG.java
Robust/src/Benchmarks/MMG/Java/Map.java
Robust/src/Benchmarks/MMG/Nor/Ghost.java
Robust/src/Benchmarks/MMG/Nor/MMG.java
Robust/src/Benchmarks/MMG/Nor/Map.java
Robust/src/Benchmarks/MMG/Tag/Ghost.java
Robust/src/Benchmarks/MMG/Tag/MMG.java
Robust/src/Benchmarks/MMG/Tag/Map.java
Robust/src/Benchmarks/MMG/Tag/Pacman.java

index 0d057a36bc095e8349f6991f3e25d07b5ad9d407..5ab35fd80255389cf0cd3a615d3ead4bf0a2a3d3 100755 (executable)
@@ -21,63 +21,19 @@ public class Ghost {
     \r
     // 0:still, 1:up, 2:down, 3:left, 4:right\r
     public void tryMove() {\r
-       // System.printString("step 1\n");\r
-       int i = 0;\r
-\r
-       // check the nearest pacman and set it as current target\r
+       //System.printString("step 1\n");\r
+       // reset the target\r
        this.m_target = -1;\r
-       int deltaX = this.m_map.m_nrofblocks;\r
-       int deltaY = this.m_map.m_nrofblocks;\r
-       int distance = deltaX * deltaX + deltaY * deltaY;\r
-       for(i = 0; i < this.m_map.m_nrofpacs; i++) {\r
-           if(this.m_map.m_pacMenX[i] != -1) {\r
-               int dx = this.m_locX - this.m_map.m_pacMenX[i];\r
-               int dy = this.m_locY - this.m_map.m_pacMenY[i];\r
-               int dd = dx*dx+dy*dy;\r
-               if(distance > dd) {\r
-                   this.m_target = i;\r
-                   distance = dd;\r
-                   deltaX = dx;\r
-                   deltaY = dy;\r
-               }\r
-           }\r
-       }\r
-       // System.printString("target: " + this.m_target + "\n");\r
-       \r
-       if(this.m_target == -1) {\r
-           // no more pacmen to chase, stay still\r
-           this.m_dx = 0;\r
-           this.m_dy = 0;\r
-           this.m_direction = this.m_map.m_ghostdirections[this.m_index] = 0;\r
-           return;\r
-       }\r
-       \r
-       // find the shortest way to the chosen target\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
-       \r
-       // get target's position\r
-       int targetx = this.m_map.m_pacMenX[this.m_target];\r
-       int targety = this.m_map.m_pacMenY[this.m_target];\r
-       int[] nextLocation = new int[2];\r
-       nextLocation[0] = nextLocation[1] = -1;\r
-       // check the target pacman's possible destination\r
-       getDestination (this.m_map.m_directions[this.m_target], targetx, targety, nextLocation);\r
-       targetx = nextLocation[0];\r
-       targety = nextLocation[1];\r
-       // target's position\r
-       Node end = this.m_map.m_mapNodes[targety * this.m_map.m_nrofblocks + targetx];\r
-       // reset the target as index of the end node\r
-       this.m_target = this.m_map.m_targets[this.m_index] = end.getIndex();\r
-       \r
-       // breadth-first traverse the graph view of the maze\r
-       // check the shortest path for the start node to the end node\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
@@ -87,7 +43,8 @@ public class Ghost {
            for(int i = 0; i < parents.length; i++) {\r
                parents[i] = -1;\r
            }\r
-           if(!BFS(start, end, parents, cuts)) {\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
@@ -96,7 +53,8 @@ public class Ghost {
            } else {\r
                // Reversely go over the parents array to find the next node to reach\r
                boolean found = false;\r
-               int index = end.getIndex();\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
@@ -128,6 +86,7 @@ public class Ghost {
                    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
@@ -152,20 +111,38 @@ public class Ghost {
     \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
+    // 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
@@ -192,7 +169,12 @@ public class Ghost {
                }\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
index d4c89bb63a613c89a038871196f499a42c754fbf..8ca790736806260c389cbc463c05abcf73a88194 100755 (executable)
@@ -67,7 +67,7 @@ public class MMG {
                    boolean death = map.check(map.m_pacmen[i]);\r
                    /*if(death) {\r
                        System.printString("Pacman " + map.m_pacmen[i].m_index + " caught!\n");\r
-                   }*/\r
+                   } */\r
                }\r
            }\r
            map.m_nrofpacs -= map.m_deathcount;\r
@@ -80,4 +80,4 @@ public class MMG {
        \r
        System.printString("Finish\n");\r
     }\r
-}
\ No newline at end of file
+}\r
index f87324d40ab3e3e816dc3c9661458ea7b35c8b4c..5cf209754d339cfb89ae3faf36a77cd1b8db63f6 100755 (executable)
@@ -176,4 +176,4 @@ public class Map {
     public boolean isfinish() {\r
        return this.m_nrofpacs == 0;\r
     }\r
-}
\ No newline at end of file
+}\r
index 228e6d8af407fef16231d73d39b25c4449d19825..91f3261412df6880205377317f27fe821ebdd590 100755 (executable)
@@ -24,62 +24,18 @@ public class Ghost {
     // 0:still, 1:up, 2:down, 3:left, 4:right
     public void tryMove() {
        //System.printString("step 1\n");
-       int i = 0;
-
-       // check the nearest pacman and set it as current target
+       // reset the target
        this.m_target = -1;
-       int deltaX = this.m_map.m_nrofblocks;
-       int deltaY = this.m_map.m_nrofblocks;
-       int distance = deltaX * deltaX + deltaY * deltaY;
-       for(i = 0; i < this.m_map.m_nrofpacs; i++) {
-           if(this.m_map.m_pacMenX[i] != -1) {
-               int dx = this.m_locX - this.m_map.m_pacMenX[i];
-               int dy = this.m_locY - this.m_map.m_pacMenY[i];
-               int dd = dx*dx+dy*dy;
-               if(distance > dd) {
-                   this.m_target = i;
-                   distance = dd;
-                   deltaX = dx;
-                   deltaY = dy;
-               }
-           }
-       }
-       // System.printString("target: " + this.m_target + "\n");
-       
-       if(this.m_target == -1) {
-           // no more pacmen to chase, stay still
-           this.m_dx = 0;
-           this.m_dy = 0;
-           this.m_direction = this.m_map.m_ghostdirections[this.m_index] = 0;
-           return;
-       }
-       
-       // find the shortest way to the chosen target
+       // 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];
-       
-       // get target's position
-       int targetx = this.m_map.m_pacMenX[this.m_target];
-       int targety = this.m_map.m_pacMenY[this.m_target];
-       int[] nextLocation = new int[2];
-       nextLocation[0] = nextLocation[1] = -1;
-       // check the target pacman's possible destination
-       getDestination (this.m_map.m_directions[this.m_target], targetx, targety, nextLocation);
-       targetx = nextLocation[0];
-       targety = nextLocation[1];
-       // target's position
-       Node end = this.m_map.m_mapNodes[targety * this.m_map.m_nrofblocks + targetx];
-       // reset the target as index of the end node
-       this.m_target = this.m_map.m_targets[this.m_index] = end.getIndex();
-       
-       // breadth-first traverse the graph view of the maze
-       // check the shortest path for the start node to the end node
        boolean set = false;
        Vector cuts = new Vector();
+       int tmptarget = 0;
        int tmpdx = 0;
        int tmpdy = 0;
        int tmpdirection = 0;
@@ -89,7 +45,8 @@ public class Ghost {
            for(int i = 0; i < parents.length; i++) {
                parents[i] = -1;
            }
-           if(!BFS(start, end, parents, cuts)) {
+           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;
@@ -98,7 +55,8 @@ public class Ghost {
            } else {
                // Reversely go over the parents array to find the next node to reach
                boolean found = false;
-               int index = end.getIndex();
+               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()) {
@@ -130,6 +88,7 @@ public class Ghost {
                    this.m_direction = 0;
                }
                if(first) {
+                   tmptarget = this.m_target;
                    tmpdx = this.m_dx;
                    tmpdy = this.m_dy;
                    tmpdirection = this.m_direction;
@@ -154,20 +113,25 @@ public class Ghost {
     
     // 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
+    // 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, Node end, int[] parents, Vector cuts) {
+    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);
-           if(access.getIndex() == end.getIndex()) {
-               // hit the end node
-               parents[parents.length - 1] = steps;
-               return true;
+           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();
@@ -356,4 +320,4 @@ public class Ghost {
        this.m_dy = 0;
        //System.printString("Ghost " + this.m_index + ": (" + this.m_locX + ", " + this.m_locY + ")\n");
     }
-}
\ No newline at end of file
+}
index 16cb4965d1fb745c317a8264c09f7e0e4f5e0b75..403924227c9c2e2bacb535f7085807daa39097b8 100755 (executable)
@@ -134,6 +134,6 @@ task next(Map map{next}) {
 }
 
 task finish(Map map{finish}) {
-    System.printString("Task Finish\n");
+   System.printString("Task Finish\n");
     taskexit(map{!finish});
-}
\ No newline at end of file
+}
index a75ec229ac2d52fb0c90f842d6bf75aa4d819f8a..650f0a624a9a4a8552f35ed877315eba7ab87aa8 100755 (executable)
@@ -177,4 +177,4 @@ public class Map {
     public boolean isfinish() {
        return this.m_nrofpacs == 0;
     }
-}
\ No newline at end of file
+}
index b8d27981ed5c56c78b5dea9c29fe790eee63abfa..d7126aedfe4ba6c733f888e2c60a75d7495b03a5 100755 (executable)
-public class Ghost {\r
-    flag move;\r
-    flag update;\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
-       int i = 0;\r
-\r
-       // check the nearest pacman and set it as current target\r
-       this.m_target = -1;\r
-       int deltaX = this.m_map.m_nrofblocks;\r
-       int deltaY = this.m_map.m_nrofblocks;\r
-       int distance = deltaX * deltaX + deltaY * deltaY;\r
-       for(i = 0; i < this.m_map.m_nrofpacs; i++) {\r
-           if(this.m_map.m_pacMenX[i] != -1) {\r
-               int dx = this.m_locX - this.m_map.m_pacMenX[i];\r
-               int dy = this.m_locY - this.m_map.m_pacMenY[i];\r
-               int dd = dx*dx+dy*dy;\r
-               if(distance > dd) {\r
-                   this.m_target = i;\r
-                   distance = dd;\r
-                   deltaX = dx;\r
-                   deltaY = dy;\r
-               }\r
-           }\r
-       }\r
-       // System.printString("target: " + this.m_target + "\n");\r
-       \r
-       if(this.m_target == -1) {\r
-           // no more pacmen to chase, stay still\r
-           this.m_dx = 0;\r
-           this.m_dy = 0;\r
-           this.m_direction = this.m_map.m_ghostdirections[this.m_index] = 0;\r
-           return;\r
-       }\r
-       \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
-       \r
-       // get target's position\r
-       int targetx = this.m_map.m_pacMenX[this.m_target];\r
-       int targety = this.m_map.m_pacMenY[this.m_target];\r
-       int[] nextLocation = new int[2];\r
-       nextLocation[0] = nextLocation[1] = -1;\r
-       // check the target pacman's possible destination\r
-       getDestination (this.m_map.m_directions[this.m_target], targetx, targety, nextLocation);\r
-       targetx = nextLocation[0];\r
-       targety = nextLocation[1];\r
-       // target's position\r
-       Node end = this.m_map.m_mapNodes[targety * this.m_map.m_nrofblocks + targetx];\r
-       // reset the target as index of the end node\r
-       this.m_target = this.m_map.m_targets[this.m_index] = end.getIndex();\r
-       \r
-       // breadth-first traverse the graph view of the maze\r
-       // check the shortest path for the start node to the end node\r
-       boolean set = false;\r
-       Vector cuts = new Vector();\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, end, parents, cuts)) {\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 = end.getIndex();\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
-                   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
-    private boolean BFS(Node start, Node end, int[] parents, Vector cuts) {\r
-       int steps = 0;\r
-       Vector toaccess = new Vector();\r
-       toaccess.addElement(start);\r
-       while(toaccess.size() > 0) {\r
-           // pull out the first one to access\r
-           Node access = (Node)toaccess.elementAt(0);\r
-           toaccess.removeElementAt(0);\r
-           if(access.getIndex() == end.getIndex()) {\r
-               // hit the end node\r
-               parents[parents.length - 1] = steps;\r
-               return true;\r
-           }\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
-       parents[parents.length - 1] = -1;\r
-       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
+public class Ghost {
+    flag move;
+    flag update;
+
+    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) {
+       //System.printString("aaa\n");
+       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);
+                   }
+               }
+           }
+       }
+       //System.printString("ccc\n");
+       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");
+    }
 }
\ No newline at end of file
index 7207bc60921b753567efe03b3e137f69a32e0d07..72884abb53bddb5d78f470dfa833571f0284ca0f 100755 (executable)
-task startup(StartupObject s{initialstate}) {\r
-    //System.printString("Task startup\n");\r
-    \r
-    int nrofpacs = 4;\r
-    int nrofghosts = 8;\r
-    Map map = new Map(nrofpacs, nrofghosts){init};\r
-    taskexit(s{!initialstate});\r
-}\r
-\r
-task initMap(Map map{init}) {\r
-    //System.printString("Task initMap\n");\r
-    \r
-    map.init();\r
-    \r
-    int i = 0;\r
-    // create ghosts\r
-    for(i = 0; i < map.m_nrofghosts; i++) {\r
-       Ghost ghost = new Ghost(7, 7, map){move};\r
-       ghost.m_index = i;\r
-       map.placeGhost(ghost);\r
-    }\r
-    // create pacmen\r
-    int tx = 14;\r
-    int ty = 14;\r
-    for(i = 0; i < map.m_nrofpacs; i++) {\r
-         Pacman pacman = new Pacman(5, 7, map){move};\r
-         pacman.setTarget(tx*(i/2), ty*(i%2));\r
-         pacman.m_index = i;\r
-         map.placePacman(pacman);\r
-         map.m_desX[i] = tx*(i/2);\r
-         map.m_desY[i] = ty*(i%2);\r
-    }\r
-    \r
-    map.m_ghostcount = 0;\r
-    map.m_paccount = 0;\r
-    \r
-    taskexit(map{!init, updateGhost});\r
-}\r
-\r
-task moveGhost(Ghost g{move}) {\r
-    //System.printString("Task moveGhost\n");\r
-    \r
-    g.tryMove();\r
-    \r
-    taskexit(g{!move, update});\r
-}\r
-\r
-task movePacman(Pacman p{move}) {\r
-    //System.printString("Task movePacman\n");\r
-    \r
-    p.tryMove();\r
-    \r
-    taskexit(p{!move, update});\r
-}\r
-\r
-task updateGhost(Map map{updateGhost}, optional Ghost g{update}) {\r
-    //System.printString("Task updateGhost\n");\r
-    \r
-    if(isavailable(g)) {\r
-       g.doMove();\r
-       map.placeGhost(g);\r
-    } else {\r
-       map.m_ghostcount++;\r
-    }\r
-    \r
-    if(map.m_ghostcount == map.m_nrofghosts) {\r
-       //map.m_nrofghosts -= map.m_failghostcount;\r
-       map.m_ghostcount = 0;\r
-       map.m_failghostcount = 0;\r
-       /*for(int i = 0; i < map.m_ghostsX.length; i++) {\r
-           System.printString("(" + map.m_ghostsX[i] + "," + map.m_ghostsY[i] + ") ");\r
-       }\r
-       System.printString("\n");*/\r
-       taskexit(map{updatePac, !updateGhost}, g{!update});\r
-    }\r
-    taskexit(g{!update});\r
-}\r
-\r
-task updatePac(Map map{updatePac}, optional Pacman p{update}) {\r
-    //System.printString("Task updatePac\n");\r
-    \r
-    if(isavailable(p)) {\r
-       p.doMove();\r
-       map.placePacman(p);\r
-       //System.printString("Pacman " + p.m_index + ": (" + map.m_pacMenX[p.m_index] + "," + map.m_pacMenY[p.m_index] + ")\n");\r
-       boolean death = map.check(p);\r
-       /*if(death) {\r
-           System.printString("Pacman " + p.m_index + " caught!\n");\r
-       }*/\r
-    } else {\r
-       map.m_deathcount++;\r
-       map.m_paccount++;\r
-    }\r
-    \r
-    boolean finish = map.m_paccount == map.m_nrofpacs;\r
-    \r
-    if(finish) {\r
-       map.m_nrofpacs -= map.m_deathcount;\r
-       //System.printString(map.m_nrofpacs + " pacmen left. \n");\r
-       if(map.isfinish()) {\r
-           taskexit(map{finish, !updatePac}, p{!update, !move});\r
-       } else {\r
-           taskexit(map{next, !updatePac}, p{!update, !move});\r
-       }\r
-    } else {\r
-       taskexit(p{!move, !update});\r
-    }\r
-}\r
-\r
-task next(Map map{next}) {\r
-    //System.printString("Task next\n");\r
-    \r
-    int i = 0;\r
-    for(i = 0; i < map.m_nrofghosts; i++) {\r
-       Ghost ghost = new Ghost(map.m_ghostsX[i], map.m_ghostsY[i], map){move};\r
-       ghost.m_index = i;\r
-       ghost.m_direction = map.m_ghostdirections[i];\r
-    }\r
-    for(i = 0; i < map.m_pacMenX.length; i++) {\r
-       if(map.m_pacMenX[i] != -1) {\r
-           // still in the map\r
-           //System.printString("new Pacman\n");\r
-           Pacman pacman = new Pacman(map.m_pacMenX[i], map.m_pacMenY[i], map){move};\r
-           pacman.setTarget(map.m_desX[i], map.m_desY[i]);\r
-           pacman.m_index = i;\r
-           pacman.m_direction = map.m_directions[i];\r
-       }\r
-    }\r
-    \r
-    map.m_paccount = 0;\r
-    map.m_deathcount = 0;\r
-    \r
-    taskexit(map{!next, updateGhost});\r
-}\r
-\r
-task finish(Map map{finish}) {\r
-    System.printString("Task Finish\n");\r
-    taskexit(map{!finish});\r
+task startup(StartupObject s{initialstate}) {
+    //System.printString("Task startup\n");
+    
+    int nrofpacs = 4;
+    int nrofghosts = 8;
+    Map map = new Map(nrofpacs, nrofghosts){init};
+    taskexit(s{!initialstate});
+}
+
+task initMap(Map map{init}) {
+    //System.printString("Task initMap\n");
+    
+    map.init();
+    
+    int i = 0;
+    // create ghosts
+    for(i = 0; i < map.m_nrofghosts; i++) {
+       Ghost ghost = new Ghost(7, 7, map){move};
+       ghost.m_index = i;
+       map.placeGhost(ghost);
+    }
+    // create pacmen
+    int tx = 14;
+    int ty = 14;
+    for(i = 0; i < map.m_nrofpacs; i++) {
+         Pacman pacman = new Pacman(5, 7, map){move};
+         pacman.setTarget(tx*(i/2), ty*(i%2));
+         pacman.m_index = i;
+         map.placePacman(pacman);
+         map.m_desX[i] = tx*(i/2);
+         map.m_desY[i] = ty*(i%2);
+    }
+    
+    map.m_ghostcount = 0;
+    map.m_paccount = 0;
+    
+    taskexit(map{!init, updateGhost});
+}
+
+task moveGhost(Ghost g{move}) {
+    //System.printString("Task moveGhost\n");
+    
+    g.tryMove();
+    
+    taskexit(g{!move, update});
+}
+
+task movePacman(Pacman p{move}) {
+    //System.printString("Task movePacman\n");
+    
+    p.tryMove();
+    
+    taskexit(p{!move, update});
+}
+
+task updateGhost(Map map{updateGhost}, optional Ghost g{update}) {
+    //System.printString("Task updateGhost\n");
+    
+    if(isavailable(g)) {
+       g.doMove();
+       map.placeGhost(g);
+    } else {
+       map.m_ghostcount++;
+    }
+    
+    if(map.m_ghostcount == map.m_nrofghosts) {
+       //map.m_nrofghosts -= map.m_failghostcount;
+       map.m_ghostcount = 0;
+       map.m_failghostcount = 0;
+       /*for(int i = 0; i < map.m_ghostsX.length; i++) {
+           System.printString("(" + map.m_ghostsX[i] + "," + map.m_ghostsY[i] + ") ");
+       }
+       System.printString("\n");*/
+       taskexit(map{updatePac, !updateGhost}, g{!update});
+    }
+    taskexit(g{!update});
+}
+
+task updatePac(Map map{updatePac}, optional Pacman p{update}) {
+    //System.printString("Task updatePac\n");
+    
+    if(isavailable(p)) {
+       p.doMove();
+       map.placePacman(p);
+       //System.printString("Pacman " + p.m_index + ": (" + map.m_pacMenX[p.m_index] + "," + map.m_pacMenY[p.m_index] + ")\n");
+       boolean death = map.check(p);
+       /*if(death) {
+           System.printString("Pacman " + p.m_index + " caught!\n");
+       }*/
+    } else {
+       map.m_deathcount++;
+       map.m_paccount++;
+    }
+    
+    boolean finish = map.m_paccount == map.m_nrofpacs;
+    
+    if(finish) {
+       map.m_nrofpacs -= map.m_deathcount;
+       //System.printString(map.m_nrofpacs + " pacmen left. \n");
+       if(map.isfinish()) {
+           taskexit(map{finish, !updatePac}, p{!update, !move});
+       } else {
+           taskexit(map{next, !updatePac}, p{!update, !move});
+       }
+    } else {
+       taskexit(p{!move, !update});
+    }
+}
+
+task next(Map map{next}) {
+    //System.printString("Task next\n");
+    
+    int i = 0;
+    for(i = 0; i < map.m_nrofghosts; i++) {
+       Ghost ghost = new Ghost(map.m_ghostsX[i], map.m_ghostsY[i], map){move};
+       ghost.m_index = i;
+       ghost.m_direction = map.m_ghostdirections[i];
+    }
+    for(i = 0; i < map.m_pacMenX.length; i++) {
+       if(map.m_pacMenX[i] != -1) {
+           // still in the map
+           //System.printString("new Pacman\n");
+           Pacman pacman = new Pacman(map.m_pacMenX[i], map.m_pacMenY[i], map){move};
+           pacman.setTarget(map.m_desX[i], map.m_desY[i]);
+           pacman.m_index = i;
+           pacman.m_direction = map.m_directions[i];
+       }
+    }
+    
+    map.m_paccount = 0;
+    map.m_deathcount = 0;
+    
+    taskexit(map{!next, updateGhost});
+}
+
+task finish(Map map{finish}) {
+    System.printString("Task Finish\n");
+    taskexit(map{!finish});
 }
\ No newline at end of file
index eb0cef24d9e65ccaaf076de22556c51515dd86f5..a75ec229ac2d52fb0c90f842d6bf75aa4d819f8a 100755 (executable)
-public class Map {\r
-    flag init;\r
-    flag updateGhost;\r
-    flag updatePac;\r
-    flag next;\r
-    flag finish;\r
-    \r
-    // maze\r
-    private int m_nrofblocks;\r
-    public int[] m_map;\r
-    public Node[] m_mapNodes;\r
-    \r
-    // pacmen information\r
-    public int m_nrofpacs;\r
-    public int[] m_pacMenX;\r
-    public int[] m_pacMenY;\r
-    public int[] m_directions;\r
-    public int[] m_desX;\r
-    public int[] m_desY;\r
-    public int m_paccount;\r
-    public int m_deathcount;\r
-    \r
-    // ghosts information\r
-    public int m_nrofghosts;\r
-    public int[] m_ghostsX;\r
-    public int[] m_ghostsY;\r
-    public int[] m_ghostdirections;\r
-    public int[] m_targets;\r
-    public int m_ghostcount;\r
-    public int m_failghostcount;\r
-    \r
-    // helper member\r
-    public Random m_r;\r
-    \r
-    public Map(int nrofpacs, int nrofghosts) {\r
-       //System.printString("step 1\n");\r
-       this.m_nrofblocks = 15;\r
-       this.m_map = new int[this.m_nrofblocks*this.m_nrofblocks];\r
-       this.m_mapNodes = new Node[this.m_nrofblocks*this.m_nrofblocks];\r
-       \r
-       this.m_nrofpacs = nrofpacs;\r
-       this.m_pacMenX = new int[this.m_nrofpacs];\r
-       this.m_pacMenY = new int[this.m_nrofpacs];\r
-       this.m_directions = new int[this.m_nrofpacs];\r
-       this.m_desX = new int[this.m_nrofpacs];\r
-       this.m_desY = new int[this.m_nrofpacs];\r
-       this.m_paccount = 0;\r
-       this.m_deathcount = 0;\r
-       \r
-       this.m_nrofghosts = nrofghosts;\r
-       this.m_ghostsX = new int[this.m_nrofghosts];\r
-       this.m_ghostsY = new int[this.m_nrofghosts];\r
-       this.m_ghostdirections = new int[this.m_nrofghosts];\r
-       this.m_targets = new int[this.m_nrofghosts];\r
-       this.m_ghostcount = 0;\r
-       this.m_failghostcount = 0;\r
-       \r
-       this.m_r = new Random();\r
-       \r
-       for(int i = 0; i < this.m_nrofblocks*this.m_nrofblocks; i++) {\r
-           this.m_map[i] = -1;\r
-           this.m_mapNodes[i] = new Node(i%this.m_nrofblocks, i/this.m_nrofblocks, i);\r
-       }\r
-       \r
-       //System.printString("step 2\n");\r
-       for(int i = 0; i < this.m_nrofpacs; i++) {\r
-           this.m_pacMenX[i] = this.m_pacMenY[i] = -1;\r
-           this.m_desX[i] = this.m_desY[i] = -1;\r
-       }\r
-       //System.printString("step 3\n");\r
-       for(int i = 0; i < this.m_nrofghosts; i++) {\r
-           this.m_ghostsX[i] = this.m_ghostsY[i] = -1;\r
-           this.m_targets[i] = -1;\r
-       }\r
-       //System.printString("step 4\n");\r
-    }\r
-    \r
-    public void init() {\r
-       // initilize the maze\r
-       int i = 0;\r
-       this.m_map[i++]=3;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=6;this.m_map[i++]=9;this.m_map[i++]=12;this.m_map[i++]=3;this.m_map[i++]=10;this.m_map[i++]=6;this.m_map[i++]=9;this.m_map[i++]=12;this.m_map[i++]=3;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=6;\r
-       this.m_map[i++]=5;this.m_map[i++]=11;this.m_map[i++]=14;this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=4;this.m_map[i++]=15;this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=4;this.m_map[i++]=11;this.m_map[i++]=14;this.m_map[i++]=5;\r
-       this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=4;this.m_map[i++]=11;this.m_map[i++]=6;this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=4;this.m_map[i++]=3;this.m_map[i++]=14;this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=4;\r
-       this.m_map[i++]=5;this.m_map[i++]=3;this.m_map[i++]=6;this.m_map[i++]=9;this.m_map[i++]=6;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=7;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=3;this.m_map[i++]=12;this.m_map[i++]=3;this.m_map[i++]=6;this.m_map[i++]=5;\r
-       this.m_map[i++]=5;this.m_map[i++]=9;this.m_map[i++]=8;this.m_map[i++]=14;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=11;this.m_map[i++]=8;this.m_map[i++]=12;this.m_map[i++]=5;\r
-       this.m_map[i++]=9;this.m_map[i++]=2;this.m_map[i++]=10;this.m_map[i++]=2;this.m_map[i++]=8;this.m_map[i++]=2;this.m_map[i++]=12;this.m_map[i++]=5;this.m_map[i++]=9;this.m_map[i++]=2;this.m_map[i++]=8;this.m_map[i++]=2;this.m_map[i++]=10;this.m_map[i++]=2;this.m_map[i++]=12;\r
-       this.m_map[i++]=6;this.m_map[i++]=5;this.m_map[i++]=7;this.m_map[i++]=5;this.m_map[i++]=7;this.m_map[i++]=5;this.m_map[i++]=11;this.m_map[i++]=8;this.m_map[i++]=14;this.m_map[i++]=5;this.m_map[i++]=7;this.m_map[i++]=5;this.m_map[i++]=7;this.m_map[i++]=5;this.m_map[i++]=3;\r
-       this.m_map[i++]=4;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=1;\r
-       this.m_map[i++]=12;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=11;this.m_map[i++]=10;this.m_map[i++]=14;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=9;\r
-       this.m_map[i++]=3;this.m_map[i++]=8;this.m_map[i++]=10;this.m_map[i++]=8;this.m_map[i++]=10;this.m_map[i++]=0;this.m_map[i++]=10;this.m_map[i++]=2;this.m_map[i++]=10;this.m_map[i++]=0;this.m_map[i++]=10;this.m_map[i++]=8;this.m_map[i++]=10;this.m_map[i++]=8;this.m_map[i++]=6;\r
-       this.m_map[i++]=5;this.m_map[i++]=3;this.m_map[i++]=2;this.m_map[i++]=2;this.m_map[i++]=6;this.m_map[i++]=5;this.m_map[i++]=15;this.m_map[i++]=5;this.m_map[i++]=15;this.m_map[i++]=5;this.m_map[i++]=3;this.m_map[i++]=2;this.m_map[i++]=2;this.m_map[i++]=6;this.m_map[i++]=5;\r
-       this.m_map[i++]=5;this.m_map[i++]=9;this.m_map[i++]=8;this.m_map[i++]=8;this.m_map[i++]=4;this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=8;this.m_map[i++]=10;this.m_map[i++]=4;this.m_map[i++]=1;this.m_map[i++]=8;this.m_map[i++]=8;this.m_map[i++]=12;this.m_map[i++]=5;\r
-       this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=6;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=11;this.m_map[i++]=2;this.m_map[i++]=14;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=3;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=4;\r
-       this.m_map[i++]=5;this.m_map[i++]=11;this.m_map[i++]=14;this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=8;this.m_map[i++]=6;this.m_map[i++]=13;this.m_map[i++]=3;this.m_map[i++]=8;this.m_map[i++]=10;this.m_map[i++]=4;this.m_map[i++]=11;this.m_map[i++]=14;this.m_map[i++]=5;\r
-       this.m_map[i++]=9;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=12;this.m_map[i++]=3;this.m_map[i++]=6;this.m_map[i++]=9;this.m_map[i++]=10;this.m_map[i++]=12;this.m_map[i++]=3;this.m_map[i++]=6;this.m_map[i++]=9;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=12; // 15*15\r
-       \r
-       // initilize the graph of the maze\r
-       for(i = 0; i < this.m_nrofblocks*this.m_nrofblocks; i++) {\r
-           int tmp = this.m_map[i];\r
-           Node tmpNode = this.m_mapNodes[i];\r
-           int locX = tmpNode.getXLoc();\r
-           int locY = tmpNode.getYLoc();\r
-           if((int)(tmp & 1) == 0) {\r
-               // can go left\r
-               if(locX == 0) {\r
-                   tmpNode.addNeighbour(this.m_mapNodes[locY * this.m_nrofblocks + this.m_nrofblocks - 1]);\r
-               } else {\r
-                   tmpNode.addNeighbour(this.m_mapNodes[i - 1]);\r
-               }\r
-           } \r
-           if((int)(tmp & 2) == 0) {\r
-               // can go up\r
-               if(locY == 0) {\r
-                   tmpNode.addNeighbour(this.m_mapNodes[(this.m_nrofblocks - 1) * this.m_nrofblocks + locX]);\r
-               } else {\r
-                   tmpNode.addNeighbour(this.m_mapNodes[(locY - 1) * this.m_nrofblocks + locX]);\r
-               }\r
-           }\r
-           if((int)(tmp & 4) == 0) {\r
-               // can go right\r
-               if(locX == this.m_nrofblocks - 1) {\r
-                   tmpNode.addNeighbour(this.m_mapNodes[locY * this.m_nrofblocks]);\r
-               } else {\r
-                   tmpNode.addNeighbour(this.m_mapNodes[i + 1]);\r
-               }\r
-           }\r
-           if((int)(tmp & 8) == 0) {\r
-               // can go down\r
-               if(locY == this.m_nrofblocks - 1) {\r
-                   tmpNode.addNeighbour(this.m_mapNodes[locX]);\r
-               } else {\r
-                   tmpNode.addNeighbour(this.m_mapNodes[(locY + 1) * this.m_nrofblocks + locX]);\r
-               }\r
-           }\r
-       }\r
-    } \r
-\r
-    public void placePacman(Pacman t) {\r
-       this.m_pacMenX[t.m_index] = t.m_locX;\r
-       this.m_pacMenY[t.m_index] = t.m_locY;\r
-       this.m_paccount++;\r
-    }\r
-    \r
-    public void placeGhost(Ghost t) {\r
-       this.m_ghostsX[t.m_index] = t.m_locX;\r
-       this.m_ghostsY[t.m_index] = t.m_locY;\r
-       this.m_ghostcount++;\r
-    }\r
-    \r
-    public boolean check(Pacman t) {\r
-       boolean death = false;\r
-       int i = 0;\r
-       while((!death) && (i < this.m_ghostsX.length)) {\r
-           if((t.m_locX == this.m_ghostsX[i]) && (t.m_locY == this.m_ghostsY[i])) {\r
-               death = true;\r
-           }\r
-           i++;\r
-       }\r
-       if((!death) && (t.m_locX == t.m_tx) && (t.m_locY == t.m_ty)) {\r
-           // reach the destination\r
-           //System.printString("Hit destination!\n");\r
-           death = true;\r
-       }\r
-       if(death) {\r
-           // pacman caught by ghost\r
-           // set pacman as death\r
-           t.m_death = true;\r
-           // kick it out\r
-           //this.m_map[t.y * this.m_nrofblocks + t.x - 1] -= 16;\r
-           this.m_deathcount++;\r
-           this.m_pacMenX[t.m_index] = -1;\r
-           this.m_pacMenY[t.m_index] = -1;\r
-       }\r
-       return death;\r
-    }\r
-    \r
-    public boolean isfinish() {\r
-       return this.m_nrofpacs == 0;\r
-    }\r
+public class Map {
+    flag init;
+    flag updateGhost;
+    flag updatePac;
+    flag next;
+    flag finish;
+    
+    // maze
+    private int m_nrofblocks;
+    public int[] m_map;
+    public Node[] m_mapNodes;
+    
+    // pacmen information
+    public int m_nrofpacs;
+    public int[] m_pacMenX;
+    public int[] m_pacMenY;
+    public int[] m_directions;
+    public int[] m_desX;
+    public int[] m_desY;
+    public int m_paccount;
+    public int m_deathcount;
+    
+    // ghosts information
+    public int m_nrofghosts;
+    public int[] m_ghostsX;
+    public int[] m_ghostsY;
+    public int[] m_ghostdirections;
+    public int[] m_targets;
+    public int m_ghostcount;
+    public int m_failghostcount;
+    
+    // helper member
+    public Random m_r;
+    
+    public Map(int nrofpacs, int nrofghosts) {
+       //System.printString("step 1\n");
+       this.m_nrofblocks = 15;
+       this.m_map = new int[this.m_nrofblocks*this.m_nrofblocks];
+       this.m_mapNodes = new Node[this.m_nrofblocks*this.m_nrofblocks];
+       
+       this.m_nrofpacs = nrofpacs;
+       this.m_pacMenX = new int[this.m_nrofpacs];
+       this.m_pacMenY = new int[this.m_nrofpacs];
+       this.m_directions = new int[this.m_nrofpacs];
+       this.m_desX = new int[this.m_nrofpacs];
+       this.m_desY = new int[this.m_nrofpacs];
+       this.m_paccount = 0;
+       this.m_deathcount = 0;
+       
+       this.m_nrofghosts = nrofghosts;
+       this.m_ghostsX = new int[this.m_nrofghosts];
+       this.m_ghostsY = new int[this.m_nrofghosts];
+       this.m_ghostdirections = new int[this.m_nrofghosts];
+       this.m_targets = new int[this.m_nrofghosts];
+       this.m_ghostcount = 0;
+       this.m_failghostcount = 0;
+       
+       this.m_r = new Random();
+       
+       for(int i = 0; i < this.m_nrofblocks*this.m_nrofblocks; i++) {
+           this.m_map[i] = -1;
+           this.m_mapNodes[i] = new Node(i%this.m_nrofblocks, i/this.m_nrofblocks, i);
+       }
+       
+       //System.printString("step 2\n");
+       for(int i = 0; i < this.m_nrofpacs; i++) {
+           this.m_pacMenX[i] = this.m_pacMenY[i] = -1;
+           this.m_desX[i] = this.m_desY[i] = -1;
+       }
+       //System.printString("step 3\n");
+       for(int i = 0; i < this.m_nrofghosts; i++) {
+           this.m_ghostsX[i] = this.m_ghostsY[i] = -1;
+           this.m_targets[i] = -1;
+       }
+       //System.printString("step 4\n");
+    }
+    
+    public void init() {
+       // initilize the maze
+       int i = 0;
+       this.m_map[i++]=3;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=6;this.m_map[i++]=9;this.m_map[i++]=12;this.m_map[i++]=3;this.m_map[i++]=10;this.m_map[i++]=6;this.m_map[i++]=9;this.m_map[i++]=12;this.m_map[i++]=3;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=6;
+       this.m_map[i++]=5;this.m_map[i++]=11;this.m_map[i++]=14;this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=4;this.m_map[i++]=15;this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=4;this.m_map[i++]=11;this.m_map[i++]=14;this.m_map[i++]=5;
+       this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=4;this.m_map[i++]=11;this.m_map[i++]=6;this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=4;this.m_map[i++]=3;this.m_map[i++]=14;this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=4;
+       this.m_map[i++]=5;this.m_map[i++]=3;this.m_map[i++]=6;this.m_map[i++]=9;this.m_map[i++]=6;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=7;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=3;this.m_map[i++]=12;this.m_map[i++]=3;this.m_map[i++]=6;this.m_map[i++]=5;
+       this.m_map[i++]=5;this.m_map[i++]=9;this.m_map[i++]=8;this.m_map[i++]=14;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=11;this.m_map[i++]=8;this.m_map[i++]=12;this.m_map[i++]=5;
+       this.m_map[i++]=9;this.m_map[i++]=2;this.m_map[i++]=10;this.m_map[i++]=2;this.m_map[i++]=8;this.m_map[i++]=2;this.m_map[i++]=12;this.m_map[i++]=5;this.m_map[i++]=9;this.m_map[i++]=2;this.m_map[i++]=8;this.m_map[i++]=2;this.m_map[i++]=10;this.m_map[i++]=2;this.m_map[i++]=12;
+       this.m_map[i++]=6;this.m_map[i++]=5;this.m_map[i++]=7;this.m_map[i++]=5;this.m_map[i++]=7;this.m_map[i++]=5;this.m_map[i++]=11;this.m_map[i++]=8;this.m_map[i++]=14;this.m_map[i++]=5;this.m_map[i++]=7;this.m_map[i++]=5;this.m_map[i++]=7;this.m_map[i++]=5;this.m_map[i++]=3;
+       this.m_map[i++]=4;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=5;this.m_map[i++]=1;
+       this.m_map[i++]=12;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=11;this.m_map[i++]=10;this.m_map[i++]=14;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=9;
+       this.m_map[i++]=3;this.m_map[i++]=8;this.m_map[i++]=10;this.m_map[i++]=8;this.m_map[i++]=10;this.m_map[i++]=0;this.m_map[i++]=10;this.m_map[i++]=2;this.m_map[i++]=10;this.m_map[i++]=0;this.m_map[i++]=10;this.m_map[i++]=8;this.m_map[i++]=10;this.m_map[i++]=8;this.m_map[i++]=6;
+       this.m_map[i++]=5;this.m_map[i++]=3;this.m_map[i++]=2;this.m_map[i++]=2;this.m_map[i++]=6;this.m_map[i++]=5;this.m_map[i++]=15;this.m_map[i++]=5;this.m_map[i++]=15;this.m_map[i++]=5;this.m_map[i++]=3;this.m_map[i++]=2;this.m_map[i++]=2;this.m_map[i++]=6;this.m_map[i++]=5;
+       this.m_map[i++]=5;this.m_map[i++]=9;this.m_map[i++]=8;this.m_map[i++]=8;this.m_map[i++]=4;this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=8;this.m_map[i++]=10;this.m_map[i++]=4;this.m_map[i++]=1;this.m_map[i++]=8;this.m_map[i++]=8;this.m_map[i++]=12;this.m_map[i++]=5;
+       this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=6;this.m_map[i++]=13;this.m_map[i++]=5;this.m_map[i++]=11;this.m_map[i++]=2;this.m_map[i++]=14;this.m_map[i++]=5;this.m_map[i++]=13;this.m_map[i++]=3;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=4;
+       this.m_map[i++]=5;this.m_map[i++]=11;this.m_map[i++]=14;this.m_map[i++]=1;this.m_map[i++]=10;this.m_map[i++]=8;this.m_map[i++]=6;this.m_map[i++]=13;this.m_map[i++]=3;this.m_map[i++]=8;this.m_map[i++]=10;this.m_map[i++]=4;this.m_map[i++]=11;this.m_map[i++]=14;this.m_map[i++]=5;
+       this.m_map[i++]=9;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=12;this.m_map[i++]=3;this.m_map[i++]=6;this.m_map[i++]=9;this.m_map[i++]=10;this.m_map[i++]=12;this.m_map[i++]=3;this.m_map[i++]=6;this.m_map[i++]=9;this.m_map[i++]=10;this.m_map[i++]=10;this.m_map[i++]=12; // 15*15
+       
+       // initilize the graph of the maze
+       for(i = 0; i < this.m_nrofblocks*this.m_nrofblocks; i++) {
+           int tmp = this.m_map[i];
+           Node tmpNode = this.m_mapNodes[i];
+           int locX = tmpNode.getXLoc();
+           int locY = tmpNode.getYLoc();
+           if((int)(tmp & 1) == 0) {
+               // can go left
+               if(locX == 0) {
+                   tmpNode.addNeighbour(this.m_mapNodes[locY * this.m_nrofblocks + this.m_nrofblocks - 1]);
+               } else {
+                   tmpNode.addNeighbour(this.m_mapNodes[i - 1]);
+               }
+           } 
+           if((int)(tmp & 2) == 0) {
+               // can go up
+               if(locY == 0) {
+                   tmpNode.addNeighbour(this.m_mapNodes[(this.m_nrofblocks - 1) * this.m_nrofblocks + locX]);
+               } else {
+                   tmpNode.addNeighbour(this.m_mapNodes[(locY - 1) * this.m_nrofblocks + locX]);
+               }
+           }
+           if((int)(tmp & 4) == 0) {
+               // can go right
+               if(locX == this.m_nrofblocks - 1) {
+                   tmpNode.addNeighbour(this.m_mapNodes[locY * this.m_nrofblocks]);
+               } else {
+                   tmpNode.addNeighbour(this.m_mapNodes[i + 1]);
+               }
+           }
+           if((int)(tmp & 8) == 0) {
+               // can go down
+               if(locY == this.m_nrofblocks - 1) {
+                   tmpNode.addNeighbour(this.m_mapNodes[locX]);
+               } else {
+                   tmpNode.addNeighbour(this.m_mapNodes[(locY + 1) * this.m_nrofblocks + locX]);
+               }
+           }
+       }
+    } 
+
+    public void placePacman(Pacman t) {
+       this.m_pacMenX[t.m_index] = t.m_locX;
+       this.m_pacMenY[t.m_index] = t.m_locY;
+       this.m_paccount++;
+    }
+    
+    public void placeGhost(Ghost t) {
+       this.m_ghostsX[t.m_index] = t.m_locX;
+       this.m_ghostsY[t.m_index] = t.m_locY;
+       this.m_ghostcount++;
+    }
+    
+    public boolean check(Pacman t) {
+       boolean death = false;
+       int i = 0;
+       while((!death) && (i < this.m_ghostsX.length)) {
+           if((t.m_locX == this.m_ghostsX[i]) && (t.m_locY == this.m_ghostsY[i])) {
+               death = true;
+           }
+           i++;
+       }
+       if((!death) && (t.m_locX == t.m_tx) && (t.m_locY == t.m_ty)) {
+           // reach the destination
+           //System.printString("Hit destination!\n");
+           death = true;
+       }
+       if(death) {
+           // pacman caught by ghost
+           // set pacman as death
+           t.m_death = true;
+           // kick it out
+           //this.m_map[t.y * this.m_nrofblocks + t.x - 1] -= 16;
+           this.m_deathcount++;
+           this.m_pacMenX[t.m_index] = -1;
+           this.m_pacMenY[t.m_index] = -1;
+       }
+       return death;
+    }
+    
+    public boolean isfinish() {
+       return this.m_nrofpacs == 0;
+    }
 }
\ No newline at end of file
index e75900eb3bdbed390d532ecf2446b37e4c92e2c9..651b90dc8e2419c095a107a55cb45a94adb57a6b 100755 (executable)
-public class Pacman {\r
-    flag move;\r
-    flag update;\r
-\r
-    public int m_locX;\r
-    public int m_locY;\r
-    public boolean m_death;\r
-    public int m_index;\r
-    public int m_direction;  // 0:still, 1:up, 2:down, 3:left, 4:right\r
-    int m_dx;\r
-    int m_dy;\r
-    public int m_tx;\r
-    public int m_ty;\r
-    Map m_map;\r
-    \r
-    public Pacman(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_death = false;\r
-       this.m_index = -1;\r
-       this.m_tx = this.m_ty = -1;\r
-       this.m_direction = 0;\r
-       this.m_map = map;\r
-    }\r
-    \r
-    public void setTarget(int x, int y) {\r
-       this.m_tx = x;\r
-       this.m_ty = y;\r
-    }\r
-    \r
-    public void tryMove() {\r
-       // decide dx & dy\r
-       \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
-       \r
-       // get target's position\r
-       int targetx = this.m_tx;\r
-       int targety = this.m_ty;\r
-       int[] nextLocation = new int[2];\r
-       nextLocation[0] = nextLocation[1] = -1;\r
-       \r
-       // target's position\r
-       Node end = this.m_map.m_mapNodes[targety * this.m_map.m_nrofblocks + targetx];\r
-       \r
-       // breadth-first traverse the graph view of the maze\r
-       // check the shortest path for the start node to the end node\r
-       boolean set = false;\r
-       Vector cuts = new Vector();\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, end, parents, cuts)) {\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 = end.getIndex();\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
-                   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(canFlee()) {\r
-                   this.m_map.m_directions[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
-    private boolean BFS(Node start, Node end, int[] parents, Vector cuts) {\r
-       int steps = 0;\r
-       Vector toaccess = new Vector();\r
-       toaccess.addElement(start);\r
-       while(toaccess.size() > 0) {\r
-           // pull out the first one to access\r
-           Node access = (Node)toaccess.elementAt(0);\r
-           toaccess.removeElementAt(0);\r
-           if(access.getIndex() == end.getIndex()) {\r
-               // hit the end node\r
-               parents[parents.length - 1] = steps;\r
-               return true;\r
-           }\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
-       parents[parents.length - 1] = -1;\r
-       return false;\r
-    }\r
-    \r
-    // This method returns true if this pacmen can flee in this direction.\r
-    private boolean canFlee () {\r
-       int steps = 0;\r
-       int locX = this.m_locX;\r
-       int locY = this.m_locY;\r
-       int[] point = new int[2];\r
-       point[0] = point[1] = -1;\r
-       \r
-       // Start off by advancing one in direction for specified location\r
-       if (this.m_direction == 1) {\r
-           // up\r
-           locY--;\r
-       } else if (this.m_direction == 2) {\r
-           // down\r
-           locY++;\r
-       } else if (this.m_direction == 3) {\r
-           // left\r
-           locX--;\r
-       } else if (this.m_direction == 4) {\r
-           // right\r
-           locX++;\r
-       }\r
-       steps++; \r
-       \r
-       boolean set = false;\r
-       // Determine next turning location.\r
-       while (!set) {\r
-           if (this.m_direction == 1 || this.m_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 (this.m_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
-                           steps++;\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
-                           steps++;\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 (this.m_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
-                           steps++;\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
-                           steps++;\r
-                       }\r
-                   }\r
-               }\r
-           }\r
-       }\r
-       \r
-       // check the least steps for the ghosts to reach point location\r
-       int chasesteps = -1;\r
-       Node end = this.m_map.m_mapNodes[point[1] * this.m_map.m_nrofblocks + point[0]];\r
-       for(int i = 0; i < this.m_map.m_ghostsX.length; i++) {\r
-           Node start = this.m_map.m_mapNodes[this.m_map.m_ghostsY[i] * this.m_map.m_nrofblocks + this.m_map.m_ghostsX[i]];\r
-           int parents[] = new int[this.m_map.m_nrofblocks * this.m_map.m_nrofblocks + 1];\r
-           for(int j = 0; j < parents.length; j++) {\r
-               parents[j] = -1;\r
-           }\r
-           if(BFS(start, end, parents, new Vector())) {\r
-               if((chasesteps == -1) ||\r
-                       (chasesteps > parents[parents.length - 1])) {\r
-                   chasesteps = parents[parents.length - 1];\r
-               }\r
-           }\r
-       }\r
-\r
-       return ((chasesteps == -1) || (steps < chasesteps));\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("Pacmen " + this.m_index + ": (" + this.m_locX + ", " + this.m_locY + ")\n");\r
-    }\r
+public class Pacman {
+    flag move;
+    flag update;
+
+    public int m_locX;
+    public int m_locY;
+    public boolean m_death;
+    public int m_index;
+    public int m_direction;  // 0:still, 1:up, 2:down, 3:left, 4:right
+    int m_dx;
+    int m_dy;
+    public int m_tx;
+    public int m_ty;
+    Map m_map;
+    
+    public Pacman(int x, int y, Map map) {
+       this.m_locX = x;
+       this.m_locY = y;
+       this.m_dx = this.m_dy = 0;
+       this.m_death = false;
+       this.m_index = -1;
+       this.m_tx = this.m_ty = -1;
+       this.m_direction = 0;
+       this.m_map = map;
+    }
+    
+    public void setTarget(int x, int y) {
+       this.m_tx = x;
+       this.m_ty = y;
+    }
+    
+    public void tryMove() {
+       // decide dx & dy
+       
+       // 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];
+       
+       // get target's position
+       int targetx = this.m_tx;
+       int targety = this.m_ty;
+       int[] nextLocation = new int[2];
+       nextLocation[0] = nextLocation[1] = -1;
+       
+       // target's position
+       Node end = this.m_map.m_mapNodes[targety * this.m_map.m_nrofblocks + targetx];
+       
+       // breadth-first traverse the graph view of the maze
+       // check the shortest path for the start node to the end node
+       boolean set = false;
+       Vector cuts = new Vector();
+       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, end, parents, cuts)) {
+               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 = end.getIndex();
+               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) {
+                   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(canFlee()) {
+                   this.m_map.m_directions[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, Node end, int[] parents, Vector cuts) {
+       int steps = 0;
+       Vector toaccess = new Vector();
+       toaccess.addElement(start);
+       while(toaccess.size() > 0) {
+           // pull out the first one to access
+           Node access = (Node)toaccess.elementAt(0);
+           toaccess.removeElementAt(0);
+           if(access.getIndex() == end.getIndex()) {
+               // hit the end node
+               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 pacmen can flee in this direction.
+    private boolean canFlee () {
+       int steps = 0;
+       int locX = this.m_locX;
+       int locY = this.m_locY;
+       int[] point = new int[2];
+       point[0] = point[1] = -1;
+       
+       // Start off by advancing one in direction for specified location
+       if (this.m_direction == 1) {
+           // up
+           locY--;
+       } else if (this.m_direction == 2) {
+           // down
+           locY++;
+       } else if (this.m_direction == 3) {
+           // left
+           locX--;
+       } else if (this.m_direction == 4) {
+           // right
+           locX++;
+       }
+       steps++; 
+       
+       boolean set = false;
+       // Determine next turning location.
+       while (!set) {
+           if (this.m_direction == 1 || this.m_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 (this.m_direction == 1) {
+                       // Check for Top Warp
+                       if (locY == 0) {
+                           point[0] = locX;
+                           point[1] = this.m_map.m_nrofblocks - 1;
+                           set = true;
+                       } else {
+                           locY--;
+                           steps++;
+                       }
+                   } else {
+                       // Check for Bottom Warp
+                       if (locY == this.m_map.m_nrofblocks - 1) {
+                           point[0] = locX;
+                           point[1] = 0;
+                           set = true;
+                       } else {
+                           locY++;
+                           steps++;
+                       }
+                   }
+               }
+           } 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 (this.m_direction == 3) {
+                       // Check for Left Warp
+                       if (locX == 0) {
+                           point[0] = this.m_map.m_nrofblocks - 1;
+                           point[1] = locY;
+                           set = true;
+                       } else {
+                           locX--;
+                           steps++;
+                       }
+                   } else {
+                       // Check for Right Warp
+                       if (locX == this.m_map.m_nrofblocks - 1) {
+                           point[0] = 0;
+                           point[1] = locY;
+                           set = true;
+                       } else {
+                           locX++;
+                           steps++;
+                       }
+                   }
+               }
+           }
+       }
+       
+       // check the least steps for the ghosts to reach point location
+       int chasesteps = -1;
+       Node end = this.m_map.m_mapNodes[point[1] * this.m_map.m_nrofblocks + point[0]];
+       for(int i = 0; i < this.m_map.m_ghostsX.length; i++) {
+           Node start = this.m_map.m_mapNodes[this.m_map.m_ghostsY[i] * this.m_map.m_nrofblocks + this.m_map.m_ghostsX[i]];
+           int parents[] = new int[this.m_map.m_nrofblocks * this.m_map.m_nrofblocks + 1];
+           for(int j = 0; j < parents.length; j++) {
+               parents[j] = -1;
+           }
+           if(BFS(start, end, parents, new Vector())) {
+               if((chasesteps == -1) ||
+                       (chasesteps > parents[parents.length - 1])) {
+                   chasesteps = parents[parents.length - 1];
+               }
+           }
+       }
+
+       return ((chasesteps == -1) || (steps < chasesteps));
+    }
+    
+    // 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("Pacmen " + this.m_index + ": (" + this.m_locX + ", " + this.m_locY + ")\n");
+    }
 }
\ No newline at end of file