program to test debug our system on
authorbdemsky <bdemsky>
Wed, 8 Apr 2009 01:24:42 +0000 (01:24 +0000)
committerbdemsky <bdemsky>
Wed, 8 Apr 2009 01:24:42 +0000 (01:24 +0000)
13 files changed:
Robust/src/Benchmarks/SingleTM/RainForest/AStarPathFinder.java [new file with mode: 0644]
Robust/src/Benchmarks/SingleTM/RainForest/Barrier.java [new file with mode: 0644]
Robust/src/Benchmarks/SingleTM/RainForest/GameMap.java [new file with mode: 0644]
Robust/src/Benchmarks/SingleTM/RainForest/Goal.java [new file with mode: 0644]
Robust/src/Benchmarks/SingleTM/RainForest/Node.java [new file with mode: 0644]
Robust/src/Benchmarks/SingleTM/RainForest/Path.java [new file with mode: 0644]
Robust/src/Benchmarks/SingleTM/RainForest/Player.java [new file with mode: 0644]
Robust/src/Benchmarks/SingleTM/RainForest/README.txt [new file with mode: 0644]
Robust/src/Benchmarks/SingleTM/RainForest/RainForest.java [new file with mode: 0644]
Robust/src/Benchmarks/SingleTM/RainForest/RockType.java [new file with mode: 0644]
Robust/src/Benchmarks/SingleTM/RainForest/TreeType.java [new file with mode: 0644]
Robust/src/Benchmarks/SingleTM/RainForest/extractLines [new file with mode: 0755]
Robust/src/Benchmarks/SingleTM/RainForest/makefile [new file with mode: 0644]

diff --git a/Robust/src/Benchmarks/SingleTM/RainForest/AStarPathFinder.java b/Robust/src/Benchmarks/SingleTM/RainForest/AStarPathFinder.java
new file mode 100644 (file)
index 0000000..0fffda1
--- /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 */
+  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/SingleTM/RainForest/Barrier.java b/Robust/src/Benchmarks/SingleTM/RainForest/Barrier.java
new file mode 100644 (file)
index 0000000..4e96379
--- /dev/null
@@ -0,0 +1,77 @@
+public class BarrierServer extends Thread {
+  int numthreads;
+  boolean done;
+  GameMap land;
+
+  public BarrierServer(int n) {
+    numthreads=n;
+    done=false;
+  }
+
+  /**
+   ** Update the age of all trees in a given map
+   ** @param land The map to be searched
+   ** @param maxage The maxage of a tree
+   ** @param rows The number of rows in the map
+   ** @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.incrementage();
+          }
+          countTrees++;
+        }
+      }
+    }
+    /* Debugging-> System.println("Tree count=  "+countTrees); */
+  }
+
+  public void run() {
+    int n;
+    ServerSocket ss=new ServerSocket(2000);
+    atomic {
+      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/SingleTM/RainForest/GameMap.java b/Robust/src/Benchmarks/SingleTM/RainForest/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/SingleTM/RainForest/Goal.java b/Robust/src/Benchmarks/SingleTM/RainForest/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/SingleTM/RainForest/Node.java b/Robust/src/Benchmarks/SingleTM/RainForest/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/SingleTM/RainForest/Path.java b/Robust/src/Benchmarks/SingleTM/RainForest/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/SingleTM/RainForest/Player.java b/Robust/src/Benchmarks/SingleTM/RainForest/Player.java
new file mode 100644 (file)
index 0000000..68246e7
--- /dev/null
@@ -0,0 +1,247 @@
+/**
+ ** 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;
+
+  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;
+    rand = new Random(30); //seed to generate random numbers
+  }
+
+  public void reset(GameMap[][] land, int row, int col, int bounds) {
+    //Teleport to new location
+    if(type == 1) { //PLANTER
+      int tempx = (rand.nextInt(Math.abs(row - 2) + 1)) + 1;
+      int tempy = (rand.nextInt(Math.abs(col - 2) + 1)) + 1;
+      if(((tempx - x) > bounds) || ((tempy - y) > bounds)) {
+        // Quickly determine the boundaries for given row and column
+        int templowx = tempx - bounds;
+        int temphighx = tempx + bounds;
+        int templowy = tempy - bounds;
+        int temphighy = tempy + bounds;
+        // define new boundaries
+        if (templowx <= 0) 
+          templowx = 1;
+        if (templowy <= 0) 
+          templowy = 1;
+        if (temphighx >= row-1) 
+          temphighx = row-2;
+        if (temphighy >= col -1) 
+          temphighy = col-2;
+
+        //
+        // Add Manual Prefetch
+        //
+
+      }
+      x = tempx;
+      y = tempy;
+      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++;
+      }
+      int tempx = (rand.nextInt(Math.abs(row - 2) + 1)) + 1;
+      int tempy = (rand.nextInt(Math.abs(col - 2) + 1)) + 1;
+      /*
+      if(((tempx - x) > bounds) || ((tempy - y) > bounds)) {
+        // Quickly determine the boundaries for given row and column
+        int templowx = tempx - bounds;
+        int temphighx = tempx + bounds;
+        int templowy = tempy - bounds;
+        int temphighy = tempy + bounds;
+        // define new boundaries
+        if (templowx <= 0) 
+          templowx = 1;
+        if (templowy <= 0) 
+          templowy = 1;
+        if (temphighx >= row-1) 
+          temphighx = row-2;
+        if (temphighy >= col -1) 
+          temphighy = col-2;
+
+        //
+        // Add Manual Prefetch
+        //
+
+      }
+      */
+      x = tempx;
+      y = tempy;
+      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) {
+    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/SingleTM/RainForest/README.txt b/Robust/src/Benchmarks/SingleTM/RainForest/README.txt
new file mode 100644 (file)
index 0000000..370b321
--- /dev/null
@@ -0,0 +1,38 @@
+Choosing where to place call to manual prefetching 
+===================================================
+Since do One move a s per the boundaries of the player
+
+Choice 0
+========
+1. Prefetch the entire land object
+
+Choice A:
+=========
+1. prefetch the entire block around player's current position in the beginning
+2. In every round keep prefetching the block around the player's current position
+   and prefetching the block around the players's goal position when goal is set
+3. Do not prefetch if goal is reset to (x,y) (-1,-1)
+
+Choice B:
+=========
+1. prefetch the entire block around player's current position in the beginning
+2. In every round prefetching the block around the players's goal position 
+   whenever a goal is set  and if goal's (tx, ty) distance from source is more
+   than the boundary BLOCK i.e if(tx - currx > BLOCK || ty - curry > BLOCK)
+   then prefetch
+
+Choice C:
+=========
+1. prefetch the entire block around player's current position in the beginning
+2. In every round check if goal is reset => no prefetching
+   In every round if player's curr position is reset and its distance is
+   greater than old(x,y) position => prefetch area around new position
+   In every round if player's goal distance is greater than source then prefetch 
+   the area around new goal position
+
+
+
+TODO
+====
+1. Find the trans commit and trans aborts per machine (write a script)
+2. Remember that the execution is not deterministic
diff --git a/Robust/src/Benchmarks/SingleTM/RainForest/RainForest.java b/Robust/src/Benchmarks/SingleTM/RainForest/RainForest.java
new file mode 100644 (file)
index 0000000..3c2ce26
--- /dev/null
@@ -0,0 +1,356 @@
+#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  16    /* How frequently/how many rounds to increment age of tree */
+#define MAXAGE              100   /* Max age of a tree */
+
+
+#define LUMBERJACK 0            /* If lumberjack */
+#define PLANTER    1            /* If a tree planter */
+
+#define INIT      0             /* Initial state */
+#define MOVING    1             /* When moving along the map */
+
+public class RainForest extends Thread {
+  /**
+   * The grid where player is playing
+   **/
+  GameMap[][] land;
+
+  /**
+   ** The shared BarrierServer object updated when trees increment age
+   ** only updated by one thread running server 
+   **/
+  BarrierServer barrserver;
+
+  /**
+   * The thread id involved 
+   **/
+  int threadid;
+
+  /**
+   * The total number of threads
+   **/
+  int numThreads;
+
+
+  public RainForest() {
+
+  }
+
+  public RainForest(GameMap[][] land, BarrierServer barrserver, int threadid, int numThreads) {
+    this.land = land;
+    this.threadid = threadid;
+    this.barrserver = barrserver;
+    this.numThreads = numThreads;
+  }
+
+  public void run() {
+    //Barrier for synchronizing moves
+    Barrier barr;
+    int id;
+    atomic {
+      id = threadid;
+    }
+    barr = new Barrier("127.0.0.1");
+
+    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;
+    //
+    //Add Manual Prefetches for this.land[lowx][lowy] to this.land[highx][highy]
+    //
+    // Quickly determine the boundaries for given row and column
+    int lowx = row - BLOCK;
+    int highx = row + BLOCK;
+    int lowy = col - BLOCK;
+    int highy = col + 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 person;
+    if((id&1) != 0) { //same as id%2
+      person = LUMBERJACK;
+    } else {
+      person = PLANTER;
+    }
+    Player gamer = new Player(person, row, col, ROW, COLUMN, BLOCK);
+    
+    // 
+    // Debug
+    // System.println("Player= "+ person+ " PosX= "+row+"  PosY= "+col);
+    //
+
+    //Do N rounds 
+    //do one move per round and synchronise
+    short[] offsets1 = new short[6];
+    for(int i = 0; i<ROUNDS; i++) {
+      atomic {
+        doOneMove(land, gamer);
+      }
+      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);
+        }
+      }
+      Barrier.enterBarrier(barr);
+          }
+  }
+
+  public static void main(String[] args) {
+    // Parse args get number of threads
+    RainForest tmprf = new RainForest();
+    RainForest.parseCmdLine(args, tmprf);
+    int numThreads= tmprf.numThreads;
+    BarrierServer mybarr;
+
+    // Init land and place rocks in boundaries
+    GameMap[][] world;
+    atomic {
+      mybarr = new BarrierServer(numThreads);
+      world = new GameMap[ROW][COLUMN];
+      int i, j;
+      for (i = 0; i < ROW; i++) {
+        for (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);
+          }
+        }
+      }
+    }
+
+    mybarr.start();
+
+    /* Set up threads */
+    RainForest[] rf;
+    atomic {
+      rf = new RainForest[numThreads];
+      for(int i=0; i<numThreads; i++) {
+        rf[i] = new RainForest(world, mybarr, i, numThreads);
+      }
+    }
+
+    /* Barrier Server waits for messages */
+    boolean waitforthreaddone = true;
+    while(waitforthreaddone) {
+      atomic {
+        if(mybarr.done)
+          waitforthreaddone = false;
+      }
+    }
+
+    /* Start threads */
+    RainForest tmp;
+    for(int i = 0; i<numThreads; i++) {
+      tmp = rf[i];
+      tmp.start();
+    }
+
+    /* Join threads */
+    for(int i = 0; i<numThreads; i++) {
+      tmp = rf[i];
+      tmp.join();
+    }
+    System.printString("Finished\n");
+  }
+
+  public void doOneMove(GameMap[][] land, Player gamer) {
+    // 1. Get start(x, y) position of the player
+    int currx = gamer.getX();
+    int curry = gamer.getY();
+
+    /* 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(land, ROW, COLUMN, BLOCK);
+        return;
+      } else {
+        if(((gamer.getGoalX() - gamer.getX()) > BLOCK) || ((gamer.getGoalY() - gamer.getY()) > BLOCK)) {
+          // Quickly determine the boundaries for given row and column
+          int lowx = gamer.goalx - BLOCK;
+          int highx = gamer.goalx + BLOCK;
+          int lowy = gamer.goaly - BLOCK;
+          int highy = gamer.goaly + 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;
+          //
+          // Add Manual Prefetch for land[lowx][lowy] to land[highx][highy]
+          //
+        }
+      }
+      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);
+        return;
+      }
+
+      nextmove.setXY(newpath.getX(0), newpath.getY(0));
+      gamer.setPosition(nextmove.getX(), nextmove.getY());
+      currx = gamer.getX();
+      curry = gamer.getY();
+      if (gamer.atDest()) {
+        if (gamer.kind() == LUMBERJACK) {
+          //If tree present, cut 
+          if (land[currx][curry].hasTree()) {
+            land[currx][curry].cutTree();
+            //
+            // Debug
+            // System.println("Cut tree");
+            //
+          } 
+        } else { // PLANTER
+          // If empty, plant tree 
+          if (land[currx][curry].hasTree() == false) {
+            if(hasMoreTrees(land, currx, curry) == false) {
+              TreeType t = new TreeType();
+              land[currx][curry].putTree(t);
+              //
+              // Debug
+              // System.println("Put tree");
+              //
+            }
+          } 
+        }
+        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();
+        // 
+        // Debug
+        // System.println("Cut tree while moving");
+        //
+      }
+      // Not at destination - do nothing
+      return;
+    }
+  }
+
+  /**
+   ** 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("");
+    }
+  }
+
+  /**
+   * Parse the command line options.
+   **/
+  public static void parseCmdLine(String args[], RainForest 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");
+  }
+
+  /**
+   ** Check the number of trees in a given area
+   ** @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].tree != null) 
+          treeCount++;
+        areaCount++;
+      }
+    }
+    if(treeCount >= (TREE_ZONE * areaCount)) {
+      return true;
+    }
+    return false;
+  }
+}
diff --git a/Robust/src/Benchmarks/SingleTM/RainForest/RockType.java b/Robust/src/Benchmarks/SingleTM/RainForest/RockType.java
new file mode 100644 (file)
index 0000000..75989c1
--- /dev/null
@@ -0,0 +1,8 @@
+/**
+ ** Rock and its properties
+ **/
+public class RockType {
+
+  public RockType() {
+  }
+}
diff --git a/Robust/src/Benchmarks/SingleTM/RainForest/TreeType.java b/Robust/src/Benchmarks/SingleTM/RainForest/TreeType.java
new file mode 100644 (file)
index 0000000..c13b981
--- /dev/null
@@ -0,0 +1,26 @@
+/**
+ ** 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;
+  }
+}
diff --git a/Robust/src/Benchmarks/SingleTM/RainForest/extractLines b/Robust/src/Benchmarks/SingleTM/RainForest/extractLines
new file mode 100755 (executable)
index 0000000..aff1b58
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+lines=$(grep -n "#" tmp1RainForest.java | cut -d: -f1 | sed '1q')
+sed '/^#/d' tmp1RainForest.java > tmpRainForest.java
diff --git a/Robust/src/Benchmarks/SingleTM/RainForest/makefile b/Robust/src/Benchmarks/SingleTM/RainForest/makefile
new file mode 100644 (file)
index 0000000..c9ba965
--- /dev/null
@@ -0,0 +1,24 @@
+MAINCLASS=RainForest
+SRC=tmp${MAINCLASS}.java \
+       Player.java \
+       TreeType.java \
+       GameMap.java \
+       RockType.java \
+       Barrier.java \
+       Goal.java \
+       Path.java \
+       Node.java \
+       AStarPathFinder.java 
+
+FLAGS=-singleTM -nooptimize -mainclass ${MAINCLASS} -debug
+
+default:
+       cpp ${MAINCLASS}.java > tmp1${MAINCLASS}.java
+       ./extractLines
+       ../../../buildscript ${FLAGS} -o ${MAINCLASS} ${SRC}
+
+clean:
+       rm tmp1RainForest.java
+       rm tmpRainForest.java
+       rm -rf tmpbuilddirectory
+       rm *.bin