java version
authoradash <adash>
Fri, 6 Mar 2009 05:10:53 +0000 (05:10 +0000)
committeradash <adash>
Fri, 6 Mar 2009 05:10:53 +0000 (05:10 +0000)
14 files changed:
Robust/src/Benchmarks/Distributed/RainForest/java/AStarPathFinder.java [new file with mode: 0644]
Robust/src/Benchmarks/Distributed/RainForest/java/BarrierNonDSM.java [new file with mode: 0644]
Robust/src/Benchmarks/Distributed/RainForest/java/GameMap.java [new file with mode: 0644]
Robust/src/Benchmarks/Distributed/RainForest/java/Goal.java [new file with mode: 0644]
Robust/src/Benchmarks/Distributed/RainForest/java/Node.java [new file with mode: 0644]
Robust/src/Benchmarks/Distributed/RainForest/java/Path.java [new file with mode: 0644]
Robust/src/Benchmarks/Distributed/RainForest/java/Player.java [new file with mode: 0644]
Robust/src/Benchmarks/Distributed/RainForest/java/RainForestClient.java [new file with mode: 0644]
Robust/src/Benchmarks/Distributed/RainForest/java/RainForestServerExample.java [new file with mode: 0644]
Robust/src/Benchmarks/Distributed/RainForest/java/RainForestServerThread.java [new file with mode: 0644]
Robust/src/Benchmarks/Distributed/RainForest/java/RockType.java [new file with mode: 0644]
Robust/src/Benchmarks/Distributed/RainForest/java/TreeType.java [new file with mode: 0644]
Robust/src/Benchmarks/Distributed/RainForest/java/extractLines [new file with mode: 0755]
Robust/src/Benchmarks/Distributed/RainForest/java/makefile [new file with mode: 0644]

diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/AStarPathFinder.java b/Robust/src/Benchmarks/Distributed/RainForest/java/AStarPathFinder.java
new file mode 100644 (file)
index 0000000..c0d7c9d
--- /dev/null
@@ -0,0 +1,332 @@
+/**
+ ** A path finder implementation that uses the AStar heuristic based algorithm
+ ** to determine a path. 
+ ** New changes for our purposes
+ **/
+public class AStarPathFinder {
+
+  /** The set of nodes that have been searched through */
+  private Vector closed;
+
+  /** The set of nodes that we do not yet consider fully searched */
+  private SortedList open;
+
+  /** The map being searched */
+  global GameMap[][] land;
+
+  /** The maximum depth of search we're willing to accept before giving up */
+  private int maxSearchDistance;
+
+  /** The complete set of nodes across the map */
+  private Node[][] nodes;
+
+  /** True if we allow diagonal movement */
+  private boolean allowDiagMovement;
+
+  /** Map size where we are searching */
+  private int rows, columns;
+
+  /**
+   ** Create a path finder with the default heuristic - closest to target.
+   ** 
+   ** @param land The map to be searched
+   ** @param maxSearchDistance The maximum depth we'll search before giving up
+   ** @param allowDiagMovement True if the search should try diagonal movement
+   **/
+  public AStarPathFinder(GameMap[][] land, int maxSearchDistance, boolean allowDiagMovement, int rows, int columns) {
+    this.land = land;
+    this.maxSearchDistance = maxSearchDistance;
+    this.allowDiagMovement = allowDiagMovement;
+    closed = new Vector();
+    open = new SortedList();
+
+    nodes = new Node[rows][columns];
+    for (int x=0;x<rows;x++) {
+      for (int y=0;y<columns;y++) {
+        nodes[x][y] = new Node(x,y);
+      }
+    }
+    this.rows = rows;
+    this.columns = columns;
+  }
+
+  /**
+   ** A description of an implementation that can find a path from one 
+   ** location on a tile map to another based on information provided
+   ** by that tile map.
+   ** 
+   ** Find a path from the starting location to the target
+   ** location avoiding blockages and attempting to honour costs 
+   ** provided by the land.
+   **
+   ** @return The path found from start to end, or null if no path can be found.
+   **/
+
+  public Path findPath(Player gamer) {
+    int tx = gamer.getGoalX();
+    int ty = gamer.getGoalY();
+    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(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
+    // tile is in the open list
+    nodes[sx][sy].cost = 0;
+    nodes[sx][sy].depth = 0;
+    closed.clear();
+    open.clear();
+    open.add(nodes[sx][sy]);
+
+    nodes[tx][ty].parent = null;
+
+    // while we haven't exceeded our max search depth
+    int maxDepth = 0;
+    while ((maxDepth < maxSearchDistance) && (open.size() != 0)) {
+      // pull out the first node in our open list, this is determined to 
+      // be the most likely to be the next step based on our heuristic
+
+      Node current = getFirstInOpen();
+
+      if (current == nodes[tx][ty]) {
+        break;
+      }
+
+      removeFromOpen(current);
+      addToClosed(current);
+
+      // search through all the neighbours of the current node evaluating
+      // them as next steps
+
+      for (int x=-1;x<2;x++) {
+        for (int y=-1;y<2;y++) {
+          // not a neighbour, its the current tile
+
+          if ((x == 0) && (y == 0)) {
+            continue;
+          }
+
+          // if we're not allowing diagonal movement then only 
+          // one of x or y can be set
+
+          if (!allowDiagMovement) {
+            if ((x != 0) && (y != 0)) {
+              continue;
+            }
+          }
+
+          // determine the location of the neighbour and evaluate it
+
+          int xp = x + current.x;
+          int yp = y + current.y;
+
+          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
+
+            int nextStepCost = current.cost + getMovementCost(current.x, current.y, xp, yp);
+            Node neighbour = nodes[xp][yp];
+
+            // if the new cost we've determined for this node is lower than 
+            // it has been previously makes sure the node has
+            // determined that there might have been a better path to get to
+            // this node so it needs to be re-evaluated
+
+            if (nextStepCost < neighbour.cost) {
+              if (inOpenList(neighbour)) {
+                removeFromOpen(neighbour);
+              }
+              if (inClosedList(neighbour)) {
+                removeFromClosed(neighbour);
+              }
+            }
+
+            // if the node hasn't already been processed and discarded then
+            // reset it's cost to our current cost and add it as a next possible
+            // step (i.e. to the open list)
+            if (!inOpenList(neighbour) && !(inClosedList(neighbour))) {
+              neighbour.cost = nextStepCost;
+              neighbour.heuristic = getHeuristicCost(xp, yp, tx, ty);
+              maxDepth = Math.max(maxDepth, neighbour.setParent(current));
+              addToOpen(neighbour);
+            }
+          }
+        }
+      }
+    }
+
+    // since we'e've run out of search 
+    // there was no path. Just return null
+    if (nodes[tx][ty].parent == null) {
+      return null;
+    }
+
+    // At this point we've definitely found a path so we can uses the parent
+    // references of the nodes to find out way from the target location back
+    // to the start recording the nodes on the way.
+
+    Path path = new Path();
+    Node target = nodes[tx][ty];
+    while (target != nodes[sx][sy]) {
+      path.prependStep(target.x, target.y);
+      target = target.parent;
+    }
+
+    // thats it, we have our path 
+    return path;
+  }
+
+  /**
+   ** 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
+   ** @param yp The y coordinate of the location to check
+   ** @return True if the location is valid for the given gamer
+   **/
+
+
+  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(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;
+  }
+
+  /**
+   ** Get the first element from the open list. This is the next
+   ** one to be searched.
+   ** 
+   ** @return The first element in the open list
+   **/
+  protected Node getFirstInOpen() {
+    Node n = (Node) open.first();
+    return n;
+  }
+
+  /**
+   ** Remove a node from the open list
+   ** 
+   ** @param node The node to remove from the open list
+   **/
+  protected void removeFromOpen(Node node) {
+    open.remove(node);
+  }
+
+  /**
+   ** Add a node to the closed list
+   ** 
+   ** @param node The node to add to the closed list
+   **/
+  protected void addToClosed(Node node) {
+    closed.addElement(node);
+  }
+
+  /**
+   ** Remove a node from the closed list
+   ** 
+   ** @param node The node to remove from the closed list
+   **/
+  protected void removeFromClosed(Node node) {
+    closed.remove(node);
+  }
+
+  /**
+   ** Check if the node supplied is in the closed list
+   ** 
+   ** @param node The node to search for
+   ** @return True if the node specified is in the closed list
+   **/
+  protected boolean inClosedList(Node node) {
+    return closed.contains(node);
+  }
+
+  /**
+   ** Check if a node is in the open list
+   ** 
+   ** @param node The node to check for
+   ** @return True if the node given is in the open list
+   **/
+  protected boolean inOpenList(Node node) {
+    return open.contains(node);
+  }
+
+  /**
+   ** Add a node to the open list
+   ** 
+   ** @param node The node to be added to the open list
+   **/
+  protected void addToOpen(Node node) {
+    open.add(node);
+  }
+
+  /**
+   ** Get the cost to move through a given location
+   ** 
+   ** @param x The x coordinate of the tile whose cost is being determined
+   ** @param y The y coordiante of the tile whose cost is being determined
+   ** @param xp The x coordinate of the neighbor target location
+   ** @param yp The y coordinate of the neighbor target location
+   ** @return The cost of movement through the given tile
+   **/
+  public int getMovementCost(int x, int y, int xp, int yp) {
+    if (Math.abs(xp - x) == 1 && Math.abs(yp - y) == 1) {
+      return 14;
+    }
+    return 10;
+  }
+
+  /**
+   *
+   * Get the cost of moving through the given tile. This can be used to 
+   ** make certain areas more desirable. 
+   ** 
+   ** @param xp The x coordinate of the tile we're moving from
+   ** @param yp The y coordinate of the tile we're moving from
+   ** @param tx The x coordinate of the tile we're moving to
+   ** @param ty The y coordinate of the tile we're moving to
+   ** @return The relative cost of moving across the given tile
+   **/
+  public int getHeuristicCost(int xp, int yp, int tx, int ty) {
+    int heur = (Math.abs(tx - xp) + Math.abs(ty - yp)) * 10;
+    return heur;
+  }
+
+  /**
+   * Used only for debugging by printing the list element's
+   * x and y coordinates
+   **/
+
+  public void debugClosedList() {
+    for(int i=0; i<closed.size(); i++) {
+      Node n = (Node) closed.elementAt(i);
+      System.print("Element "+i+": n.getX()= "+n.getX()+" n.getY()= "+n.getY()+ "\n");
+    }
+    System.printString("\n");
+  }
+}
diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/BarrierNonDSM.java b/Robust/src/Benchmarks/Distributed/RainForest/java/BarrierNonDSM.java
new file mode 100644 (file)
index 0000000..7aec621
--- /dev/null
@@ -0,0 +1,50 @@
+public class BarrierServer extends Thread {
+  int numthreads;
+  boolean done;
+
+  public BarrierServer(int n) {
+    numthreads=n;
+    done=false;
+  }
+
+  public void run() {
+    int n;
+    ServerSocket ss=new ServerSocket(2000);
+    n=numthreads;
+    done=true;
+    Socket ar[]=new Socket[n];
+    for(int i=0; i<n; i++) {
+      ar[i]=ss.accept();
+    }
+
+    while(true) {
+      for(int j=0; j<n; j++) {
+        Socket s=ar[j];
+        byte b[]=new byte[1];
+        while(s.read(b)!=1) {
+          ;
+        }
+      }
+      byte b[]=new byte[1];
+      b[0]= (byte) 'A';
+      for(int j=0; j<n; j++)
+        ar[j].write(b);
+    }
+  }
+}
+
+public class Barrier {
+  Socket s;
+  public Barrier(String name) {
+    s=new Socket(name, 2000);
+  }
+
+  public static void enterBarrier(Barrier barr) {
+    byte b[]=new byte[1];
+    b[0]=(byte)'A';
+    barr.s.write(b);
+    while(barr.s.read(b)!=1) {
+      ;
+    }
+  }
+}
diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/GameMap.java b/Robust/src/Benchmarks/Distributed/RainForest/java/GameMap.java
new file mode 100644 (file)
index 0000000..0168e0e
--- /dev/null
@@ -0,0 +1,65 @@
+/** 
+ ** The main Map that is shared across machines 
+ ** The description for the data we're pathfinding over. This provides the contract
+ ** between the data being searched (i.e. the in game map) and the path finding
+ ** generic tools
+ **/
+
+public class GameMap {
+  private TreeType tree;
+  private RockType rock;
+
+  public GameMap() {
+    tree = null;
+    rock = null;
+  }
+
+  public boolean hasTree() {
+    if (tree != null) {
+      return true;
+    }
+    return false;
+  }
+
+  public boolean hasRock() {
+    if (rock != null) {
+      return true;
+    } 
+    return false;
+  }
+
+  public void putTree(TreeType t) {
+    tree = t;
+  }
+
+  public void putRock(RockType r) {
+    rock = r;
+  }
+
+  public void cutTree() {
+    tree = null;
+  }
+
+  public boolean isEmpty() {
+    if (tree == null && rock == null) {
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   ** Only for Debugging by printing the map
+   ** Called after every round
+   **/
+  public void print() {
+    if (tree != null) { 
+      System.print("T ");
+      return;
+    } 
+    if (rock != null) {
+      System.print("o ");
+      return;
+    }
+    System.print(". ");
+  }
+}
diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/Goal.java b/Robust/src/Benchmarks/Distributed/RainForest/java/Goal.java
new file mode 100644 (file)
index 0000000..7e03ac9
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ ** Saves the X and Y coordinates of a single tile in a Map
+ **/
+
+public class Goal {
+  private int locX;
+  private int locY;
+
+  public Goal() {
+    locX = 0;
+    locY = 0;
+  }
+
+  public Goal(int x, int y) {
+    locX = x;
+    locY = y;
+  }
+
+  public void setXY(int x, int y) {
+    locX = x;
+    locY = y;
+  }
+
+  public int getX() {
+    return locX;
+  }
+
+  public int getY() {
+    return locY;
+  }
+}
diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/Node.java b/Robust/src/Benchmarks/Distributed/RainForest/java/Node.java
new file mode 100644 (file)
index 0000000..7c10bcd
--- /dev/null
@@ -0,0 +1,198 @@
+/**
+ ** A single node in the search graph
+ ** Has same dimensions as the Map where we are searching
+ **/
+private class Node {
+  /** The x coordinate of the node */
+  private int x;
+  /** The y coordinate of the node */
+  private int y;
+  /** The path cost for this node */
+  private int cost;
+  /** The parent of this node, how we reached it in the search */
+  private Node parent;
+  /** The heuristic cost of this node */
+  private int heuristic;
+  /** The search depth of this node */
+  private int depth;
+
+  /**
+   **Create a new node
+   ** 
+   ** @param x The x coordinate of the node
+   ** @param y The y coordinate of the node
+   **/
+  public Node(int x, int y) {
+    this.x = x;
+    this.y = y;
+  }
+
+  /**
+   ** Set the parent of this node
+   ** 
+   ** @param parent The parent node which lead us to this node
+   ** @return The depth we have no reached in searching
+   **/
+  public int setParent(Node parent) {
+    depth = parent.depth + 1;
+    this.parent = parent;
+
+    return depth;
+  }
+
+  /**
+   ** compareTo(Object)
+   **/
+  public int compareTo(Object other) {
+    Node o = (Node) other;
+
+    int f = heuristic + cost;
+    int of = o.heuristic + o.cost;
+
+    if (f < of) {
+      return -1;
+    } else if (f > of) {
+      return 1;
+    } else {
+      return 0;
+    }
+  }
+
+  /**
+   ** @return The cost of the heuristic
+   **/
+  public int getHeuristic() {
+    return heuristic;
+  }
+
+
+  /**
+   ** @return The actual cost of traversal 
+   **/
+  public int getCost() {
+    return cost;
+  }
+
+  /**
+   ** Only for Debugging by printing contents of Node
+   **/
+  public void debugNode() {
+    System.println("x= "+ x + " y= "+ y + " cost= " + cost + " heuristic= "+ heuristic + " depth= " + depth);
+  }
+
+  public int getX() {
+    return x;
+  }
+
+  public int getY() {
+    return y;
+  }
+}
+
+/**
+ ** A simple sorted list
+ **
+ **/
+class SortedList {
+  /** The list of elements */
+  private Vector list;
+
+  public SortedList() {
+    list = new Vector();
+  }
+  /**
+   ** Retrieve the first element from the list
+   **  
+   ** @return The first element from the list
+   **/
+  public Object first() {
+    Object o = list.elementAt(0);
+    return o;
+  }
+
+  /**
+   ** Empty the list
+   **/
+  public void clear() {
+    list.clear();
+  }
+
+  /**
+   **Add an element to the list - causes sorting
+   ** 
+   ** @param o The element to add
+   **/
+  public void add(Object o) {
+    list.addElement(o);
+    Node tmp = (Node) o;
+    int min = tmp.heuristic + tmp.cost;
+    int i;
+    int index = 0;
+    /* Move the Node with minimum cost to the first position */
+    for(i = 0; i < list.size(); i++) {
+      if(min > totalCost(list.elementAt(i))) {
+        min = totalCost(list.elementAt(i));
+        index = i;
+      }
+    }
+
+    if(index < 0 || index >=list.size()) {
+      System.printString("Illegal SortedList.add\n");
+      System.exit(-1);
+      return;
+    }
+
+    Object temp = list.elementAt(0);
+    list.setElementAt(list.elementAt(index),0);
+    list.setElementAt(temp, index);
+  }
+
+  /**
+   **@return fixed cost + heuristic cost
+   **/
+  public int totalCost(Object o) {
+    Node tmp = (Node) o;
+    int cost = tmp.getHeuristic() + tmp.getCost();
+    return cost;
+  }
+
+
+  /**
+   ** Remove an element from the list
+   ** 
+   ** @param o The element to remove
+   **/
+  public void remove(Object o) {
+    list.remove(o);
+  }
+
+  /**
+   ** Get the number of elements in the list
+   ** 
+   ** @return The number of element in the list
+   **/
+  public int size() {
+    return list.size();
+  }
+
+  /**
+   ** Check if an element is in the list
+   ** 
+   ** @param o The element to search for
+   ** @return True if the element is in the list
+   **/
+  public boolean contains(Object o) {
+    return list.contains(o);
+  }
+
+  /**
+   ** Only for Debugging by printing contents of openlist
+   **/
+  public void debugOpenList() {
+    for(int i=0; i<list.size(); i++) {
+      Node n = (Node) list.elementAt(i);
+      System.print("Element "+i+": n.getX()= "+n.getX()+" n.getY()= "+n.getY()+ "\n");
+    }
+    System.printString("\n");
+  }
+}
diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/Path.java b/Robust/src/Benchmarks/Distributed/RainForest/java/Path.java
new file mode 100644 (file)
index 0000000..7426d49
--- /dev/null
@@ -0,0 +1,149 @@
+/**
+ ** A path determined by some path finding algorithm. A series of steps from
+ ** the starting location to the target location. This includes a step for the
+ ** initial location.
+ ** 
+ **/
+public class Path {
+  /** The list of steps building up this path */
+  private Vector steps;
+
+  /**
+   ** Create an empty path
+   **/
+  public Path() {
+    steps = new Vector();
+  }
+
+  /**
+   ** Get the length of the path, i.e. the number of steps
+   ** 
+   ** @return The number of steps in this path
+   **/
+  public int getLength() {
+    return steps.size();
+  }
+
+  /**
+   ** Get the step at a given index in the path
+   ** 
+   ** @param index The index of the step to retrieve. Note this should
+   ** be >= 0 and < getLength();
+   ** @return The step information, the position on the map.
+   **/
+  public Step getStep(int index) {
+    return (Step) steps.elementAt(index);
+  }
+
+  /**
+   ** Get the x coordinate for the step at the given index
+   ** 
+   ** @param index The index of the step whose x coordinate should be retrieved
+   ** @return The x coordinate at the step
+   **/
+  public int getX(int index) {
+    return getStep(index).x;
+  }
+
+  /**
+   ** Get the y coordinate for the step at the given index
+   ** 
+   ** @param index The index of the step whose y coordinate should be retrieved
+   ** @return The y coordinate at the step
+   **/
+  public int getY(int index) {
+    return getStep(index).y;
+  }
+
+  /**
+   ** Append a step to the path.  
+   ** 
+   ** @param x The x coordinate of the new step
+   ** @param y The y coordinate of the new step
+   **/
+  public void appendStep(int x, int y) {
+    steps.addElement(new Step(x,y));
+  }
+
+  /**
+   ** Prepend a step to the path.  
+   ** 
+   ** @param x The x coordinate of the new step
+   ** @param y The y coordinate of the new step
+   **/
+  public void prependStep(int x, int y) {
+    steps.insertElementAt(new Step(x, y), 0);
+  }
+
+  /**
+   ** Check if this path contains the given step
+   ** 
+   ** @param x The x coordinate of the step to check for
+   ** @param y The y coordinate of the step to check for
+   ** @return True if the path contains the given step
+   **/
+  public boolean contains(int x, int y) {
+    return steps.contains(new Step(x,y));
+  }
+
+}
+
+/**
+ ** A single step within the path
+ **/
+class Step {
+  /** The x coordinate at the given step */
+  private int x;
+  /** The y coordinate at the given step */
+  private int y;
+
+  /**
+   ** Create a new step
+   ** 
+   ** @param x The x coordinate of the new step
+   ** @param y The y coordinate of the new step
+   **/
+  public Step(int x, int y) {
+    this.x = x;
+    this.y = y;
+  }
+
+  /**
+   ** Get the x coordinate of the new step
+   ** 
+   ** @return The x coodindate of the new step
+   **/
+  public int getX() {
+    return x;
+  }
+
+  /**
+   ** Get the y coordinate of the new step
+   ** 
+   ** @return The y coodindate of the new step
+   **/
+  public int getY() {
+    return y;
+  }
+
+  /**
+   ** Same as Object#hashCode()
+   **/
+  public int hashCode() {
+    return x*y;
+  }
+
+  /**
+   ** Same as Object#equals(Object)
+   ** 
+   **/
+  public boolean equals(Object other) {
+    if (other instanceof Step) {
+      Step o = (Step) other;
+      if((o.x == x) && (o.y == y)) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/Player.java b/Robust/src/Benchmarks/Distributed/RainForest/java/Player.java
new file mode 100644 (file)
index 0000000..66704b1
--- /dev/null
@@ -0,0 +1,205 @@
+/**
+ ** An object representing the entity in the game that
+ ** 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.
+ ** 
+ ** a) Saves the current X and Y coordinates for a Player
+ ** b) Saves the destination goalX and goalY
+ ** c) Determines the boundary using high/low X and Y coordinates for
+ **    the current position
+ ** d) Keeps track of the STATE of the player
+ **/
+public class Player {
+  private int type;
+  private int x;
+  private int y;
+  private int lowx, highx;
+  private int lowy, highy;
+  private int state;
+  private int goalx, goaly;
+  private int rows, cols;
+  private Random rand;
+  private char action;
+
+  public Player(int type, int x, int y) {
+    this.type = type;
+    this.x = x;
+    this.y = y;
+  }
+
+  public Player(int type, int x, int y, int rows, int cols, int bounds) {
+    this.type = type;
+    this.x = x;
+    this.y = y;
+    this.rows = rows;
+    this.cols = cols;
+    lowx = x - bounds;
+    highx = x + bounds;
+    lowy = y - bounds;
+    highy = y + bounds;
+    // define new boundaries
+    if (lowx <= 0) 
+      lowx = 1;
+    if (lowy <= 0) 
+      lowy = 1;
+    if (highx >= rows) 
+      highx = rows-2;
+    if (highy >= cols) 
+      highy = cols-2;
+    this.state = 0; //0 => INIT state
+    this.goalx = 0;
+    this.goaly = 0;
+    rand = new Random(30); //seed to generate random numbers
+    this.action = 'M'; //initalized to moving
+  }
+
+  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) {
+    lowx = x - bounds;
+    highx = x + bounds;
+    lowy = y - bounds;
+    highy = y + bounds;
+    // define new boundaries
+    if (lowx <= 0) 
+      lowx = 1;
+    if (lowy <= 0) 
+      lowy = 1;
+    if (highx >= rows-1) 
+      highx = rows-2;
+    if (highy >= cols-1) 
+      highy = cols-2;
+    return;
+  }
+
+  /**
+   ** @return if Player is lumberjack or a planter
+   **/
+  public int kind() {
+    return type;
+  }
+
+  /**
+   ** Sets the X and Y coordinate of the Player
+   **/
+  public void setPosition(int x, int y) {
+    this.x = x;
+    this.y = y;
+  }
+
+  //public void setNewPosition(int x, int y, int row, int col, int bounds) {
+  public void setNewPosition(int row, int col, int bounds) {
+    //setPosition(x, y);
+    setBoundary(bounds, row, col);
+    goalx = -1;
+    goaly = -1;
+  }
+
+  public int getX() {
+    return x;
+  } 
+  
+  public int getY() { 
+    return y; 
+  }
+
+  /** Sets state of the Player **/
+
+  public void setState(int state) {
+    this.state = state;
+    return;
+  }
+
+  public int getState() {
+    return this.state;
+  }
+
+  /** Randomly finds a goal in a given boundary for player
+   ** @return 0 on success and -1 when you cannot find any new goal
+   **/
+  public int findGoal(GameMap[][] land) {
+    /* Try setting the goal for try count times
+     * 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++) {
+      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)) {
+        goalx = row;
+        goaly = col;
+        return 0;
+      }
+      if (type == 0 && (land[row][col].hasTree() == true) && (land[row][col].hasRock() == false)) {
+        goalx = row;
+        goaly = col;
+        return 0;
+      }
+    }
+    return -1;
+  }
+
+  public void setGoal(int x, int y) {
+    goalx = x;
+    goaly = y;
+  }
+
+  public int getGoalX() {
+    return goalx;
+  }
+
+  public int getGoalY() {
+    return goaly;
+  }
+
+  /**
+   ** Only for debugging
+   **/
+  public debugPlayer() {
+    System.println("State= "+ state+ " Curr X=  "+ x + " Curr Y=  " + y + " Goal X=  "+ goalx + " Goal Y= "+ goaly + " Type = " + type);
+  }
+
+  /**
+   ** @return true if reached the goal else return false
+   **/
+  public boolean atDest() {
+    if (x == goalx && y == goaly) {
+      return true;
+    } 
+    return false;
+  }
+}
diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/RainForestClient.java b/Robust/src/Benchmarks/Distributed/RainForest/java/RainForestClient.java
new file mode 100644 (file)
index 0000000..fb21986
--- /dev/null
@@ -0,0 +1,350 @@
+#define ROW                 100  /* columns in the map */
+#define COLUMN              100  /* rows of in the map */
+#define ROUNDS              200   /* 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 LUMBERJACK          0    /* If lumberjack */
+#define PLANTER             1    /* If a tree planter */
+#define SHIFT               2    /* Shift to new location */
+
+#define INIT                0    /* Initial state */
+#define MOVING              1    /* When moving along the map */
+
+public class RainForestClient {
+
+  public RainForestClient() {
+
+  }
+
+  public static void main(String[] args) {
+    int seed;
+    if(args.length>0) {
+      seed = Integer.parseInt(args[0]);
+    }
+
+    Random rand = new Random(seed);
+    RainForestClient rfc = new RainForestClient();
+    Socket sock = new Socket("dw-8.eecs.uci.edu",9002);
+
+    /* Read player type from Server */
+    byte b[] = new byte[1]; //read planter or lumber jack
+    int numbytes;
+    while((numbytes = sock.read(b)) < 1) {
+      ;
+    }
+    String str = (new String(b)).subString(0, numbytes);
+    int person;
+    if(str.equalsIgnoreCase("L")) {
+      person = LUMBERJACK;
+    }
+    if(str.equalsIgnoreCase("P")) {
+      person = PLANTER;
+    }
+
+    //Generate a random x and y coordinate to start with
+    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;
+    Player gamer = new Player(person, row, col, ROW, COLUMN, BLOCK);
+
+    //
+    //Debug
+    //
+    /* System.println("Person= "+person+" LocX= "+row+" LocY= "+col); */
+
+    GameMap[][] land = new GameMap[ROW][COLUMN];
+    for(int i = 0; i<ROW; i++) {
+      for(int j = 0; j<COLUMN; j++) {
+        land[i][j] = new GameMap();
+      }
+    }
+    byte buf[] = new byte[9];
+    String temp;
+    Barrier barr;
+    barr =  new Barrier("128.195.175.79");
+    for(int i = 0; i<ROUNDS; i++) {
+      // 
+      // Send the continue to read
+      //
+      sock.write(rfc.fillBytes("U",i));
+
+      //
+      //Read information of land object from Server
+      //
+      while(true) {
+        numbytes = sock.read(buf);
+        temp = (new String(buf)).subString(0, numbytes);
+        if(temp.startsWith("sentLand"))
+          break;
+        rfc.extractCoordinates(buf, land);
+      }
+
+      //Debug 
+      //rfc.printLand(land, ROW, COLUMN);
+
+      //
+      //Do rounds 
+      //do one move per round and write to server
+      //
+      rfc.doOneMove(land, gamer, sock);
+
+      //Receive ACK from server and do player updates
+      while((numbytes = sock.read(b)) < 1) {
+        ;
+      }
+      if((b[0] == (byte)'S') && ((gamer.action == 'C') || gamer.action == 'P')) {
+        //Update position and boundaries
+        gamer.setNewPosition(ROW, COLUMN, BLOCK);
+        gamer.setState(INIT);
+      }
+      
+      //Retry if failure
+      if(b[0] == (byte)'F'){
+        i--;          
+      }
+
+      //Synchronize threads
+      Barrier.enterBarrier(barr);
+    }
+
+    //
+    //Special character "T" to terminate computation
+    //
+    sock.write(rfc.fillBytes("T", 0));
+    sock.close();
+  }
+
+  public void extractCoordinates(byte[] b, GameMap[][] land) {
+    int posX = getX(b); 
+    int posY = getY(b);
+
+    if(b[0] == (byte) 'T') {
+      land[posX][posY].putTree(new TreeType());
+    }
+    if(b[0] == (byte) 'R') {
+      land[posX][posY].putRock(new RockType());
+    }
+  }
+
+  int getX(byte[] b) {
+    int val;
+    val = ((b[1] & 0xFF) << 24) + ((b[2] & 0xFF) << 16) + ((b[3] & 0xFF) << 8) + (b[4] & 0xFF);
+    return val;
+  }
+
+  int getY(byte[] b) {
+    int val;
+    val = ((b[5] & 0xFF) << 24) + ((b[6] & 0xFF) << 16) + ((b[7] & 0xFF) << 8) + (b[8] & 0xFF);
+    return val;
+  }
+
+  /**
+   ** Only for Debugging 
+   **/
+  public void printLand(GameMap[][] land, int row, int col) {
+    for (int i = 0; i < row; i++) {
+      for (int j = 0; j < col; j++) {
+        land[i][j].print();
+      }
+      System.println("");
+    }
+  }
+
+  /**
+   ** One move by the gamer
+   ** @param land The map to be searched
+   ** @param gamer The player making the move
+   ** @return 0 is success , -1 otherwise
+   **/
+  public int doOneMove(GameMap[][] land, Player gamer, Socket sock) {
+    // 1. Get start(x, y) position of the player
+    int currx = gamer.getX();
+    int curry = gamer.getY();
+
+    //
+    //Debug
+    //
+    /* printLand(land, ROW, COLUMN); */
+
+    // 2. Get type of player (lumberjack or planter)
+    int type = gamer.kind();
+
+    //3. Change states
+    if (gamer.getState() == INIT) {
+
+      //gamer.debugPlayer(); 
+
+      if (gamer.findGoal(land) < 0) {
+        gamer.reset(land, ROW, COLUMN, BLOCK);
+        gamer.action = 'M';
+        sock.write(fillBytes(SHIFT, 0, 0));
+        return 0;
+      }
+
+      //gamer.debugPlayer(); 
+
+      gamer.setState(MOVING);
+    } 
+
+    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 start to goal */
+      if(newpath == null) {
+        //
+        //Debug
+        //
+        /* System.println("Path from ("+currx+","+curry+") to ("+gamer.getGoalX()+","+gamer.getGoalY()+") is null"); */
+
+        gamer.reset(land, ROW, COLUMN, BLOCK);
+        gamer.setState(INIT);
+        gamer.action = 'M';
+        sock.write(fillBytes(SHIFT, 0, 0));
+        return 0;
+      }
+
+      nextmove.setXY(newpath.getX(0), newpath.getY(0));
+      gamer.setPosition(nextmove.getX(), nextmove.getY());
+      //
+      //Debug
+      //gamer.debugPlayer();
+      //
+      currx = gamer.getX();
+      curry = gamer.getY();
+      if (gamer.atDest()) {
+        if (gamer.kind() == LUMBERJACK) {
+          if (land[currx][curry].hasTree()) {
+            //Send next move to server
+            gamer.action = 'C';
+            sock.write(fillBytes(LUMBERJACK, currx, curry));
+            return 0;
+          } 
+          sock.write(fillBytes(SHIFT, 0, 0));
+          return 0;
+        } else { // PLANTER
+          if (land[currx][curry].hasTree() == false) {
+            if(hasMoreTrees(land, currx, curry) == false) {
+              //Send next move to server
+              gamer.action = 'P';
+              sock.write(fillBytes(PLANTER, currx, curry));
+              return 0;
+            }
+            sock.write(fillBytes(SHIFT, 0, 0));
+            return 0;
+          } 
+          sock.write(fillBytes(SHIFT, 0, 0));
+          return 0;
+        } 
+      } else {
+        if(land[currx][curry].hasTree() && gamer.kind() == LUMBERJACK) { //Cut trees along the way
+          //
+          //Send next move to server
+          //
+          gamer.action = 'C';
+          sock.write(fillBytes(LUMBERJACK, currx, curry));
+          return 0;
+        }
+        // Not at destination - do nothing
+        gamer.action = 'M';
+        sock.write(fillBytes(SHIFT, 0, 0));
+      }
+      
+      return 0;
+    }
+  }
+
+  /**
+   ** Check the number of trees in a given area
+   **
+   ** @param land The map to be searched
+   ** @param x The x coordinate to plant a tree
+   ** @param y The y coordinate to plant a tree
+   **
+   ** @return true if area covered more than the zone for trees 
+   **/
+  public boolean hasMoreTrees(GameMap[][] land, int x, int y) {
+    int lowx = x - BLOCK;
+    int highx = x + BLOCK;
+    int lowy = y - BLOCK;
+    int highy = y + BLOCK;
+    // define new boundaries
+    if (lowx <= 0) 
+      lowx = 1;
+    if (lowy <= 0) 
+      lowy = 1;
+    if (highx >= ROW-1) 
+      highx = ROW-2;
+    if (highy >= COLUMN-1) 
+      highy = COLUMN-2;
+    int treeCount = 0;
+    int areaCount = 0;
+    for(int i = lowx; i < highx; i++) {
+      for(int j = lowy; j < highy; j++) {
+        if(land[i][j].hasTree()) 
+          treeCount++;
+        areaCount++;
+      }
+    }
+    if(treeCount >= (TREE_ZONE * areaCount)) {
+      return true;
+    }
+    return false;
+  }
+
+  /** Fill byte array
+   ** @param type The player kind 1 => Planter 0=> Lumberjack 2=> Shift to new location
+   ** @param x The x coordinate of player
+   ** @param y The y coordinate of player
+   **/
+  byte[] fillBytes(int type, int x, int y) {
+    byte[] b = new byte[9]; //1 byte for the move + 8 bytes for x and y
+    if(type == PLANTER)
+      b[0] = (byte)'P'; //planting
+    if(type == LUMBERJACK)
+      b[0] = (byte)'C'; // cutting
+    if(type == SHIFT)
+      b[0] = (byte)'M'; //moving
+    for(int i = 1; i<5; i++) {
+      int offset = (3-(i-1)) * 8;
+      b[i] = (byte) ((x >> offset) & 0xFF);
+    }
+    for(int i = 5; i<9; i++) {
+      int offset = (3-(i-5)) * 8;
+      b[i] = (byte) ((y >> offset) & 0xFF);
+    }
+    return b;
+  }
+
+  /** Fill byte array for round index and termination
+   ** @param x The x coordinate of player
+   ** @param y The y coordinate of player
+   **/
+  byte[] fillBytes(String str, int index) {
+    byte[] b = new byte[5]; //1 byte for the control msg + 4 bytes for roundIndex 
+    if(str.equalsIgnoreCase("U")) {
+      b[0] = (byte)'U';
+    }
+
+    if(str.equalsIgnoreCase("T")) {
+      b[0] = (byte)'T';
+    }
+
+    for(int i = 1; i<5; i++) {
+      int offset = (3-(i-1)) * 8;
+      b[i] = (byte) ((index >> offset) & 0xFF);
+    }
+
+    return b;
+  }
+}
diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/RainForestServerExample.java b/Robust/src/Benchmarks/Distributed/RainForest/java/RainForestServerExample.java
new file mode 100644 (file)
index 0000000..6dde612
--- /dev/null
@@ -0,0 +1,105 @@
+#define ROW                 100  /* columns in the map */
+#define COLUMN              100  /* rows of in the map */
+
+public class RainForestServerExample {
+  private int numThreads;
+
+  public RainForestServerExample() {
+
+  }
+
+  public static int main(String args[]) {
+    int numThreads;
+    if(args.length>0) {
+      numThreads = Integer.parseInt(args[0]);
+    }
+
+    /**
+     * Create shared Map 
+     **/
+    // Init land and place rocks in boundaries
+    GameMap[][] world;
+    world =  new GameMap[ROW][COLUMN];
+    for (int i = 0; i < ROW; i++) {
+      for (int j = 0; j < COLUMN; j++) {
+        world[i][j] = new GameMap();
+        if (j == 0 || j == COLUMN-1) {
+          RockType r = new RockType();
+          world[i][j].putRock(r);
+        }
+        if (i == 0 || i == ROW-1) {
+          RockType r = new RockType();
+          world[i][j].putRock(r);
+        }
+      }
+    }
+
+    ServerSocket ss = new ServerSocket(9002);
+    acceptConnection(ss, world, numThreads);
+  }
+
+  public static void acceptConnection(ServerSocket ss, GameMap[][] world, int numThreads) {
+    //
+    //Start Barrier server
+    //
+    BarrierServer mybarr = new BarrierServer(numThreads);
+    mybarr.start();
+
+    /* Set up threads */
+    RainForestServerThread[] rft = new RainForestServerThread[numThreads];
+    for(int i=0; i<numThreads; i++) {
+      Socket s = ss.accept();
+      rft[i] = new RainForestServerThread(world, s, ROW, COLUMN, i);
+    }
+
+    /* Wait for messages */
+    boolean waitforthreaddone = true;
+    while(waitforthreaddone) {
+      if(mybarr.done)
+        waitforthreaddone = false;
+    }
+
+    /* Start threads */
+    for(int i = 0; i<numThreads; i++) {
+      rft[i].start();
+    }
+
+    /* Join threads */
+    for(int i = 0; i<numThreads; i++) {
+      rft[i].join();
+    }
+
+    System.printString("Finished\n");
+  }
+
+  /**
+   * Parse the command line options.
+   **/
+  public static void parseCmdLine(String args[], RainForestServerExample rf) {
+    int i = 0;
+    String arg;
+    while(i < args.length && args[i].startsWith("-")) {
+      arg = args[i++];
+      //check options
+      if(arg.equals("-N")) {
+        if(i < args.length) {
+          rf.numThreads = new Integer(args[i++]).intValue();
+        }
+      } else if(arg.equals("-h")) {
+        rf.usage();
+      }
+    }
+
+    if(rf.numThreads == 0)
+      rf.usage();
+  }
+
+  /**
+   * The usage routine which describes the program options.
+   **/
+  public void usage() {
+    System.println("usage: ./RainForestN.bin master -N <threads>\n");
+    System.printString("    -N the number of threads\n");
+    System.printString("    -h help with usage\n");
+  }
+}
diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/RainForestServerThread.java b/Robust/src/Benchmarks/Distributed/RainForest/java/RainForestServerThread.java
new file mode 100644 (file)
index 0000000..ebd370a
--- /dev/null
@@ -0,0 +1,236 @@
+#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  10   /* How frequently/how many rounds to increment age of tree */
+#define MAXAGE              100  /* Max age of a tree */
+
+public class RainForestServerThread extends Thread {
+  GameMap[][] land;
+  Socket sock;
+  int rows;
+  int cols;
+  int id;
+
+  public RainForestServerThread(GameMap[][] land, Socket sock, int rows, int cols, int id) {
+    this.land = land;
+    this.sock = sock;
+    this.rows = rows;
+    this.cols = cols;
+    this.id = id;
+  }
+
+  public void run() {
+    /* Assign a player to be a lumberjack or planter */
+    byte b[] = new byte[1];     //1 byte control to determine if lumberjack/planter
+    if((id&1) != 0) 
+      b[0] = (byte)'L';
+    else
+      b[0] = (byte)'P';
+    sock.write(b);
+
+    //
+    //Debugging
+    //
+    /* printLand(land, rows, cols); */
+
+    byte[] buf = new byte[5];    //1 byte to decide if terminate or continue + 4 bytes for getting the round index
+    int numbytes;
+    byte[] buffer = new byte[9]; //1 byte presence of tree/rocks + 8 bytes for their x and y coordinates
+
+    while(true) {
+
+      /* Check for termination character */
+      while((numbytes = sock.read(buf)) < 5) {
+        //System.println("Looping in 2");
+        ;
+      }
+
+      String str1 = (new String(buf)).subString(0, 1);
+
+      /* terminate if opcode sent is "t" */
+      if(str1.equalsIgnoreCase("T")) {
+        break;
+      } else if(str1.equalsIgnoreCase("U")) {
+        int roundIndex = getX(buf); //Get the index from client
+        System.println("round id = " + roundIndex);
+        if((roundIndex % AGEUPDATETHRESHOLD) == 0 && (id == 0)) { 
+          /* Update age of all trees in a Map */
+          updateAge(land, MAXAGE, rows, cols);
+        }
+
+        /* Data representing presence/absence of trees */
+        for(int i=0 ; i<rows; i++) {
+          for(int j=0; j<cols; j++) {
+            sock.write(fillBytes(land, i, j, buffer));
+          }
+        }
+
+        StringBuffer header = new StringBuffer("sentLand");
+        String temp_str = new String(header);
+        sock.write(temp_str.getBytes());
+        header = null;
+        temp_str = null;
+
+        /* Read client's move */
+        while((numbytes = sock.read(buffer)) < 9) {
+          ;
+        }
+        str1 = (new String(buffer)).subString(0, 1);
+
+        /* Take actions such as cutting or planting or moving */
+        if(str1.equalsIgnoreCase("C")) {
+          int val;
+          if((val = doTreeCutting(land, buffer)) == 0) {
+            System.println("Cutting\n");
+            b[0] = (byte)'S';
+          } else {
+            System.println("Retrying to cut\n");
+            b[0] = (byte)'F';
+          }
+          sock.write(b);
+        }
+
+        if(str1.equalsIgnoreCase("P")) {
+          int val;
+          if((val = doTreePlanting(land, buffer)) == 0) {
+            System.println("Planting\n");
+            b[0] = (byte)'S';
+          } else {
+            System.println("Retrying to plant\n");
+            b[0] = (byte)'F';
+          }
+          sock.write(b);
+        }
+
+        if(str1.equalsIgnoreCase("M")) {
+          System.println("Moving to goal\n");
+          b[0] = (byte)'S';
+          sock.write(b);
+        }
+      }
+    } //end while
+
+    //
+    //Debugging
+    //printLand(land, rows, cols);
+    //
+    sock.close();
+
+  }//end run()
+
+  /**
+   ** fill byte array
+   **/
+  byte[] fillBytes(GameMap[][] land, int x, int y, byte[] b) {
+    if(land[x][y].hasTree()) 
+      b[0] = (byte)'T';
+    if(land[x][y].hasRock())
+      b[0] = (byte)'R';
+    if(!land[x][y].hasRock() && !land[x][y].hasTree())
+      b[0] = (byte)'N';
+    for(int i = 1; i<5; i++) {
+      int offset = (3-(i-1)) * 8;
+      b[i] = (byte) ((x >> offset) & 0xFF);
+    }
+    for(int i = 5; i<9; i++) {
+      int offset = (3-(i-5)) * 8;
+      b[i] = (byte) ((y >> offset) & 0xFF);
+    }
+    return b;
+  }
+
+  /**
+   ** Only for Debugging 
+   **/
+  public void printLand(GameMap[][] land, int row, int col) {
+    for (int i = 0; i < row; i++) {
+      for (int j = 0; j < col; j++) {
+        land[i][j].print();
+      }
+      System.println("");
+    }
+  }
+
+  /**
+   * Synchronize threads that are cutting trees
+   **/
+  synchronized int doTreeCutting(GameMap[][] land, byte[] b) {
+    int posX = getX(b);
+    int posY = getY(b);
+
+    /* Cut, if tree present */
+    if(land[posX][posY].hasTree()) {
+      land[posX][posY].cutTree();
+      return 0;
+    }
+
+    return -1;
+  }
+
+  /**
+   * Synchronize threads that are planting trees
+   **/
+  synchronized int doTreePlanting(GameMap[][] land, byte[] b) {
+    int posX = getX(b);
+    int posY = getY(b);
+
+    /* Plant if no tree */
+    if(!land[posX][posY].hasTree()) {
+      TreeType t = new TreeType();
+      land[posX][posY].putTree(t);
+      return 0;
+    }
+
+    return -1;
+  }
+
+  /**
+   ** Get X coordinate
+   **/
+  int getX(byte[] b) {
+    int val;
+    val = ((b[1] & 0xFF) << 24) + ((b[2] & 0xFF) << 16) + ((b[3] & 0xFF) << 8) + (b[4] & 0xFF);
+    return val;
+  }
+
+  /**
+   ** Get Y coordinate
+   **/
+  int getY(byte[] b) {
+    int val;
+    val = ((b[5] & 0xFF) << 24) + ((b[6] & 0xFF) << 16) + ((b[7] & 0xFF) << 8) + (b[8] & 0xFF);
+    return val;
+  }
+
+  /**
+   ** Update age of trees in a map
+   ** @param land: The map
+   ** @param maxage: The max age of a tree
+   ** @param rows: Rows in the map
+   ** @param cols: Cols in the map
+   **/
+
+  /**
+   * Synchronize threads that are cutting trees
+   **/
+  synchronized 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].hasTree()) {
+          if(land[i][j].tree.getage() > maxage) {
+            land[i][j].tree = null;
+          } else {
+            land[i][j].tree.incrementage();
+          }
+          countTrees++;
+        }
+      }
+    }
+    //
+    //Debug
+    //System.println("Tree count=  "+countTrees); 
+    //
+  }
+}
diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/RockType.java b/Robust/src/Benchmarks/Distributed/RainForest/java/RockType.java
new file mode 100644 (file)
index 0000000..cdb308d
--- /dev/null
@@ -0,0 +1,8 @@
+/**
+ ** Rock and its properties
+ **/
+public class RockType {
+  public RockType() {
+
+  }
+}
diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/TreeType.java b/Robust/src/Benchmarks/Distributed/RainForest/java/TreeType.java
new file mode 100644 (file)
index 0000000..90ee4d6
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ ** Tree and its properties
+ **/
+public class TreeType {
+  private int age;
+
+  public TreeType() {
+    age = 0;
+  }
+
+  public int getage() {
+    return age;
+  }
+
+  public void incrementage() {
+    age++;
+  }
+
+  public void incrementTenYrs() {
+    age = age + 10;
+  }
+
+  public void incrementFiveYrs() {
+    age = age + 5;
+  }
+
+  public int hashCode() {
+    return age;
+  }
+
+  public String toString() {
+    return String.valueOf(age);
+  }
+}
diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/extractLines b/Robust/src/Benchmarks/Distributed/RainForest/java/extractLines
new file mode 100755 (executable)
index 0000000..16ec912
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/sh
+lines=$(grep -n "#" tmp1RainForestClient.java | cut -d: -f1 | sed '1q')
+sed '/^#/d' tmp1RainForestClient.java > tmpRainForestClient.java
+lines=$(grep -n "#" tmp1RainForestServerExample.java | cut -d: -f1 | sed '1q')
+sed '/^#/d' tmp1RainForestServerExample.java > tmpRainForestServerExample.java
+lines=$(grep -n "#" tmp1RainForestServerThread.java | cut -d: -f1 | sed '1q')
+sed '/^#/d' tmp1RainForestServerThread.java > tmpRainForestServerThread.java
diff --git a/Robust/src/Benchmarks/Distributed/RainForest/java/makefile b/Robust/src/Benchmarks/Distributed/RainForest/java/makefile
new file mode 100644 (file)
index 0000000..1291086
--- /dev/null
@@ -0,0 +1,42 @@
+MAINCLASS1=RainForestServerExample
+MAINCLASS2=RainForestClient
+SRC=tmp${MAINCLASS1}.java \
+       tmpRainForestServerThread.java \
+       TreeType.java \
+       GameMap.java \
+       RockType.java \
+       Player.java \
+       BarrierNonDSM.java
+
+SRC1 =tmp${MAINCLASS2}.java \
+         GameMap.java \
+         TreeType.java \
+         RockType.java \
+         Goal.java \
+         Path.java \
+         Node.java \
+         Player.java \
+         AStarPathFinder.java \
+         BarrierNonDSM.java
+
+         
+FLAGS1= -thread -nooptimize -debug -mainclass ${MAINCLASS1}
+FLAGS2= -thread -nooptimize -debug -mainclass ${MAINCLASS2}
+
+default:
+       cpp RainForestServerExample.java > tmp1RainForestServerExample.java
+       cpp RainForestServerThread.java > tmp1RainForestServerThread.java
+       cpp RainForestClient.java > tmp1RainForestClient.java
+       ./extractLines
+       ../../../../buildscript ${FLAGS1} -o Server ${SRC}
+       ../../../../buildscript ${FLAGS2} -o Client ${SRC1}
+
+clean:
+       rm -rf tmpbuilddirectory
+       rm *.bin
+       rm tmp1RainForestServerExample.java
+       rm tmp1RainForestServerThread.java
+       rm tmp1RainForestClient.java
+       rm tmpRainForestServerExample.java
+       rm tmpRainForestServerThread.java
+       rm tmpRainForestClient.java