bug fixes to prevent starvation of a lumberjack
authoradash <adash>
Tue, 3 Mar 2009 23:37:46 +0000 (23:37 +0000)
committeradash <adash>
Tue, 3 Mar 2009 23:37:46 +0000 (23:37 +0000)
Robust/src/Benchmarks/Distributed/RainForest/dsm/AStarPathFinder.java
Robust/src/Benchmarks/Distributed/RainForest/dsm/Barrier.java
Robust/src/Benchmarks/Distributed/RainForest/dsm/Player.java
Robust/src/Benchmarks/Distributed/RainForest/dsm/RainForest.java
Robust/src/Benchmarks/Distributed/RainForest/dsm/makefile

index 55f511d93d86e0c91370c1ca8af8d1a9adb882f5..c0d7c9d977cb0e4c1fe742b2b3fc6b26c5e61637 100644 (file)
@@ -68,9 +68,18 @@ public class AStarPathFinder {
     int sx = gamer.getX();
     int sy = gamer.getY();
 
+    int type = gamer.kind();
+
     // easy first check, if the destination is blocked, we can't get there
-    if(land[tx][ty].hasTree() || land[tx][ty].hasRock()) {
-      return null;
+
+    if(type == 1) { //1 => PLANTER
+      if(land[tx][ty].hasTree() || land[tx][ty].hasRock()) {
+        return null;
+      }
+    } else { //LUMBERJACK
+      if((!land[tx][ty].hasTree()) || land[tx][ty].hasRock()) {
+        return null;
+      }
     }
 
     // initial state for A*. The closed group is empty. Only the starting
@@ -123,7 +132,7 @@ public class AStarPathFinder {
           int xp = x + current.x;
           int yp = y + current.y;
 
-          if (isValidLocation(sx,sy,xp,yp)) {
+          if (isValidLocation(gamer,sx,sy,xp,yp)) {
             // the cost to get to this node is cost the current plus the movement
             // cost to reach this node. Note that the heursitic value is only used
             // in the sorted open list
@@ -183,6 +192,7 @@ public class AStarPathFinder {
   /**
    ** Check if a given location is valid for the supplied gamer
    ** 
+   ** @param gamer The Player moving in the map
    ** @param sx The starting x coordinate
    ** @param sy The starting y coordinate
    ** @param xp The x coordinate of the location to check
@@ -191,12 +201,18 @@ public class AStarPathFinder {
    **/
 
 
-  public boolean isValidLocation(int sx, int sy, int xp, int yp) {
+  public boolean isValidLocation(Player gamer, int sx, int sy, int xp, int yp) {
     boolean invalid = (xp <= 0) || (yp <= 0) || (xp >= rows-1) || (yp >= columns-1);
 
     if ((!invalid) && ((sx != xp) || (sy != yp))) {
-      if (land[xp][yp].hasTree() || land[xp][yp].hasRock()) {
-        invalid = true;
+      if(gamer.kind() == 1) { //1=> PLANTER
+        if (land[xp][yp].hasTree() || land[xp][yp].hasRock()) {
+          invalid = true;
+        }
+      } else { //LUMBERJACK
+        if (land[xp][yp].hasRock()) {
+          invalid = true;
+        }
       }
     }
     return !invalid;
index cba383ceb43a8e495090dc3f7ee7e8fbc80614c3..927f849757ccb31854d0c9749d0f608a2c1f0759 100644 (file)
@@ -15,17 +15,20 @@ public class BarrierServer extends Thread {
    ** @param cols The number of columns in the map
    **/
   public void updateAge(GameMap[][] land, int maxage, int rows, int cols) {
+    int countTrees = 0;
     for(int i = 0; i<rows; i++) {
       for(int j = 0; j<cols; j++) {
         if(land[i][j].tree != null) {
           if(land[i][j].tree.getage() > maxage) {
             land[i][j].tree = null;
           } else {
-            land[i][j].tree.incrementFiveYrs();
+            land[i][j].tree.incrementage();
           }
+          countTrees++;
         }
       }
     }
+    /* Debugging-> System.println("Tree count=  "+countTrees); */
   }
 
   public void run() {
index aaf89be655355d44311743d0ccab104c2dfd09f2..b7f83a97a1ecb4cea10649499429d1e1d3e43594 100644 (file)
@@ -1,6 +1,6 @@
 /**
  ** An object representing the entity in the game that
- ** is going to moving along the path. This allows us to pass around entity/state
+ ** is going to move along the path. This allows us to pass around entity/state
  ** information to determine whether a particular tile is blocked, or how much
  ** cost to apply on a particular tile.
  ** 
@@ -14,24 +14,25 @@ public class Player {
   private int type;
   private int x;
   private int y;
-  private int id;
   private int lowx, highx;
   private int lowy, highy;
   private int state;
   private int goalx, goaly;
+  private int rows, cols;
+  private Random rand;
 
   public Player(int type, int x, int y) {
     this.type = type;
     this.x = x;
     this.y = y;
-    id = -1;
   }
 
-  public Player(int type, int x, int y, int id, int rows, int cols, int bounds) {
+  public Player(int type, int x, int y, int rows, int cols, int bounds) {
     this.type = type;
     this.x = x;
     this.y = y;
-    this.id = id;
+    this.rows = rows;
+    this.cols = cols;
     lowx = x - bounds;
     highx = x + bounds;
     lowy = y - bounds;
@@ -45,16 +46,39 @@ public class Player {
       highx = rows-2;
     if (highy >= cols) 
       highy = cols-2;
+    rand = new Random(30); //seed to generate random numbers
   }
 
-  public void reset(int row, int col, int bounds) {
-    int seed = x + y;
-    Random rand = new Random(seed);
-    x = (rand.nextInt(Math.abs(row - 2) + 1)) + 1;
-    y = (rand.nextInt(Math.abs(col - 2) + 1)) + 1;
-    goalx = -1;
-    goaly = -1;
-    setBoundary(bounds, row, col);
+  public void reset(GameMap[][] land, int row, int col, int bounds) {
+    //Teleport to new location
+    if(type == 1) { //PLANTER
+      x = (rand.nextInt(Math.abs(row - 2) + 1)) + 1;
+      y = (rand.nextInt(Math.abs(col - 2) + 1)) + 1;
+      goalx = -1;
+      goaly = -1;
+      setBoundary(bounds, row, col);
+    } 
+
+    if(type == 0) { //LUMBERJACK
+      int trycount = 5; //try a few more times before teleporting 
+      int i = 0;
+      while(i<trycount) {
+        int locx = (rand.nextInt(Math.abs(row - 2) + 1)) + 1;
+        int locy = (rand.nextInt(Math.abs(col - 2) + 1)) + 1;
+        if(!land[locx][locy].hasRock() && land[locx][locy].hasTree()) {
+          goalx = locx;
+          goaly = locy;
+          state = 1; //1=> MOVING state
+          return;
+        }
+        i++;
+      }
+      x = (rand.nextInt(Math.abs(row - 2) + 1)) + 1;
+      y = (rand.nextInt(Math.abs(col - 2) + 1)) + 1;
+      goalx = -1;
+      goaly = -1;
+      setBoundary(bounds, row, col);
+    }
   }
 
   public void setBoundary(int bounds, int rows, int cols) {
@@ -120,13 +144,13 @@ public class Player {
    **/
   public int findGoal(GameMap[][] land) {
     /* Try setting the goal for try count times
-     * if not possible , then select a completely new goal
+     * if not possible, then select a completely new goal
      */
     int trycount = (highx - lowx) + (highy - lowy);
     int i;
 
+    Random rand = new Random(0);
     for (i = 0; i < trycount; i++) {
-      Random rand = new Random(i);
       int row = (rand.nextInt(Math.abs(highx - lowx)) + 1) + lowx;
       int col = (rand.nextInt(Math.abs(highy - lowy)) + 1) + lowy;
       if (type == 1 && (land[row][col].hasTree() == false) && (land[row][col].hasRock() == false)) {
@@ -140,9 +164,6 @@ public class Player {
         return 0;
       }
     }
-    if (i == trycount) {
-      /* System.println("Timeout trying ... \n") Only for Debugging */
-    }
     return -1;
   }
 
@@ -163,7 +184,7 @@ public class Player {
    ** Only for debugging
    **/
   public debugPlayer() {
-    System.println("State= "+ state+ " Curr X=  "+ x + " Curr Y=  " + y + " Goal X=  "+ goalx + " Goal Y= "+ goaly + " Type = " + type + "\n");
+    System.println("State= "+ state+ " Curr X=  "+ x + " Curr Y=  " + y + " Goal X=  "+ goalx + " Goal Y= "+ goaly + " Type = " + type);
   }
 
   /**
index f5b0e1f6a7d780682a7bb0d65c2f8a278582b0d8..e7d0cc976063d9515ff958e3621a84a71bbbeb08 100644 (file)
@@ -1,11 +1,11 @@
-#define ROW                 7     /* columns in the map */
-#define COLUMN                 /* rows of in the map */
-#define ROUNDS              2  /* Number of moves by each player */
+#define ROW                 100   /* columns in the map */
+#define COLUMN              100   /* rows of in the map */
+#define ROUNDS              256  /* Number of moves by each player */
 #define PLAYERS             20    /* Number of Players when num Players != num of client machines */
 #define RATI0               0.5   /* Number of lumberjacks to number of planters */
 #define BLOCK               3     /* Area around the gamer to consider */
 #define TREE_ZONE           0.4   /* Max percentage of trees in a zone */
-#define AGEUPDATETHRESHOLD      /* How frequently/how many rounds to increment age of tree */
+#define AGEUPDATETHRESHOLD  10    /* How frequently/how many rounds to increment age of tree */
 #define MAXAGE              100   /* Max age of a tree */
 
 
@@ -21,11 +21,6 @@ public class RainForest extends Thread {
    **/
   GameMap[][] land;
 
-  /**
-   * The gamer per thread: shared array where players do not see each other
-   **/
-  Player gamer;
-
   /**
    ** The shared BarrierServer object updated when trees increment age
    ** only updated by one thread running server 
@@ -47,29 +42,45 @@ public class RainForest extends Thread {
 
   }
 
-  public RainForest(GameMap[][] land, Player gamer, BarrierServer barrserver, int threadid, int numThreads) {
+  public RainForest(GameMap[][] land, BarrierServer barrserver, int threadid, int numThreads) {
     this.land = land;
-    this.gamer = gamer;
     this.threadid = threadid;
     this.barrserver = barrserver;
     this.numThreads = numThreads;
   }
 
   public void run() {
-    //Do N rounds 
-    //do one move per round and synchronise
+    //Barrier for synchronizing moves
     Barrier barr;
     int id;
     atomic {
       id = threadid;
     }
     barr = new Barrier("128.195.136.162");
+
+    Random rand = new Random(id);
+    // Generate random numbers between 1 and row index/column index
+    int maxValue = ROW - 1;
+    int minValue = 1;
+    int row = (rand.nextInt(Math.abs(maxValue - minValue) + 1)) + minValue;
+    maxValue = COLUMN -1;
+    int col = (rand.nextInt(Math.abs(maxValue - minValue) + 1)) + minValue;
+    int person;
+    if((id&1) == 0) { //same as id%2
+      person = LUMBERJACK;
+    } else {
+      person = PLANTER;
+    }
+    Player gamer = new Player(person, row, col, ROW, COLUMN, BLOCK);
+
+    //Do N rounds 
+    //do one move per round and synchronise
     for(int i = 0; i<ROUNDS; i++) {
       atomic {
         doOneMove(land, gamer);
       }
       Barrier.enterBarrier(barr);
-      if((i%AGEUPDATETHRESHOLD) == 0 && id == 0) {
+      if((i&15) == 0 && id == 0) { //same as i%AGEUPDATETHRESHOLD
         /* Update age of all trees in a Map */
         atomic {
           barrserver.updateAge(land, MAXAGE, ROW, COLUMN);
@@ -119,37 +130,12 @@ public class RainForest extends Thread {
 
     mybarr.start(mid[0]);
 
-    // Create P players
-    // For each thread, init either a lumberjack/planter
-    Player[] players;
-    atomic {
-      players = global new Player[numThreads];
-      for (int i = 0; i < numThreads; i++) {
-        Random rand = new Random(i);
-        /* Generate random numbers between 1 and row index/column index*/
-        int maxValue = ROW - 1;
-        int minValue = 1;
-        int row = (rand.nextInt(Math.abs(maxValue - minValue) + 1)) + minValue;
-        maxValue = COLUMN -1;
-        int col = (rand.nextInt(Math.abs(maxValue - minValue) + 1)) + minValue;
-        int type = rand.nextInt(2);
-        int person;
-        if (type == 0) {
-          person = LUMBERJACK;
-        } else {
-          person = PLANTER;
-        }
-        players[i] = global new Player(person, row, col, i, ROW, COLUMN, BLOCK);
-      }
-    }
-
     /* Set up threads */
     RainForest[] rf;
     atomic {
       rf = global new RainForest[numThreads];
       for(int i=0; i<numThreads; i++) {
-        Random rand = new Random(i);
-        rf[i] = global new RainForest(world, players[i], mybarr, i, numThreads);
+        rf[i] = global new RainForest(world, mybarr, i, numThreads);
       }
     }
 
@@ -186,33 +172,33 @@ public class RainForest extends Thread {
     int currx = gamer.getX();
     int curry = gamer.getY();
 
-    // Only for Debugging
     /* printLand(land, ROW, COLUMN); */
 
     // 2. Get type of player (lumberjack or planter)
     int type = gamer.kind();
 
+    /* gamer.debugPlayer(); */
+    //3. Change states
     if (gamer.getState() == INIT) {
-
       if (gamer.findGoal(land) < 0) {
-        gamer.reset(ROW, COLUMN, BLOCK);
+        gamer.reset(land, ROW, COLUMN, BLOCK);
         return;
       }
       gamer.setState(MOVING);
-      /* gamer.debugPlayer(); Only for debugging */
     } 
 
     if (gamer.getState() == MOVING) {
       Goal nextmove = new Goal();
-
       int maxSearchDistance = 10;
       boolean allowDiagMovement = true;
+      /* Find shortest path using AStar algo from start to goal */
       AStarPathFinder apath =  new  AStarPathFinder(land, maxSearchDistance, allowDiagMovement, ROW, COLUMN);
       Path newpath = apath.findPath(gamer);
 
-      /* Reset state if there in no path from src to destination */
+      /* Reset state if there in no path from start to goal */
       if(newpath == null) {
-        gamer.reset(ROW, COLUMN, BLOCK);
+        /* System.println("Path from ("+currx+","+curry+") to ("+gamer.getGoalX()+","+gamer.getGoalY()+") is null"); */
+        gamer.reset(land, ROW, COLUMN, BLOCK);
         gamer.setState(INIT);
         return;
       }
@@ -227,8 +213,6 @@ public class RainForest extends Thread {
           if (land[currx][curry].hasTree()) {
             land[currx][curry].cutTree();
           } 
-          gamer.setNewPosition(currx, curry, ROW, COLUMN, BLOCK);
-          gamer.setState(INIT);
         } else { // PLANTER
           // If empty, plant tree 
           if (land[currx][curry].hasTree() == false) {
@@ -237,12 +221,13 @@ public class RainForest extends Thread {
               land[currx][curry].putTree(t);
             }
           } 
-          gamer.setNewPosition(currx, curry, ROW, COLUMN, BLOCK);
-          gamer.setState(INIT);
         }
-      } 
+        gamer.setNewPosition(currx, curry, ROW, COLUMN, BLOCK);
+        gamer.setState(INIT);
+      } else if(land[currx][curry].hasTree() && gamer.kind() == LUMBERJACK) { //Cut trees along the way
+        land[currx][curry].cutTree();
+      }
       // Not at destination - do nothing
-      /* Debug -> gamer.debugPlayer(); */
       return;
     }
   }
index 6b6c699547631a3b9d3e89d447cbcf70232a0a8e..af0c5ad47d9a505d945591583f90494eca5c5069 100644 (file)
@@ -10,7 +10,7 @@ SRC=tmp${MAINCLASS}.java \
        Node.java \
        AStarPathFinder.java 
 
-FLAGS1=-dsm -nooptimize -debug -mainclass ${MAINCLASS}
+FLAGS1=-dsm -optimize -transstats -mainclass ${MAINCLASS}
 FLAGS2=-dsm -dsmcaching -optimize -mainclass ${MAINCLASS}
 FLAGS3=-dsm -dsmcaching -prefetch -optimize -mainclass ${MAINCLASS} -trueprob 0.90
 FLAGS4=-dsm -dsmcaching -rangeprefetch -optimize -mainclass ${MAINCLASS} -trueprob 0.90