add debugs for now
[IRC.git] / Robust / src / Benchmarks / Recovery / Game / recovery / RainForest.java
1 #define ROW                 400   /* columns in the map */
2 #define COLUMN              100   /* rows of in the map */
3 #define ROUNDS              512  /* Number of moves by each player */
4 #define PLAYERS             20    /* Number of Players when num Players != num of client machines */
5 #define RATI0               0.5   /* Number of lumberjacks to number of planters */
6 #define BLOCK               3     /* Area around the gamer to consider */
7 #define TREE_ZONE           0.4   /* Max percentage of trees in a zone */
8 #define AGEUPDATETHRESHOLD  16    /* How frequently/how many rounds to increment age of tree */
9 #define MAXAGE              100   /* Max age of a tree */
10
11
12 #define LUMBERJACK 0            /* If lumberjack */
13 #define PLANTER    1            /* If a tree planter */
14
15 #define INIT      0             /* Initial state */
16 #define MOVING    1             /* When moving along the map */
17
18 public class RainForest extends Thread {
19   /**
20    * The grid where player is playing
21    **/
22   GameMap[][] land;
23
24   /**
25    ** The shared BarrierServer object updated when trees increment age
26    ** only updated by one thread running server 
27    **/
28   Barrier barr;
29
30   /**
31    * The thread id involved 
32    **/
33   int threadid;
34
35   /**
36    * The total number of threads
37    **/
38   int numThreads;
39
40
41   public RainForest() {
42
43   }
44
45   public RainForest(GameMap[][] land, Barrier barr, int threadid, int numThreads) {
46     this.land = land;
47     this.threadid = threadid;
48     this.barr = barr;
49     this.numThreads = numThreads;
50   }
51
52   public void run() {
53     int id, nthreads;
54     threadinfo[] mytinfo;
55     atomic {
56       id = threadid;
57       mytinfo = barr.tinfo;
58       nthreads = numThreads;
59     }
60
61     Random rand = new Random(id);
62     // Generate random numbers between 1 and row index/column index
63     int maxValue = ROW - 1;
64     int minValue = 1;
65     int row = (rand.nextInt(Math.abs(maxValue - minValue) + 1)) + minValue;
66     maxValue = COLUMN -1;
67     int col = (rand.nextInt(Math.abs(maxValue - minValue) + 1)) + minValue;
68     int person;
69     if((id&1) != 0) { //same as id%2
70       person = LUMBERJACK;
71     } else {
72       person = PLANTER;
73     }
74     Player gamer = new Player(person, row, col, ROW, COLUMN, BLOCK);
75     
76     // 
77     // Debug
78     // System.println("Player= "+ person+ " PosX= "+row+"  PosY= "+col);
79     //
80
81     //Do N rounds 
82     //do one move per round and synchronise
83     for(int i = 0; i<ROUNDS; i++) {
84       System.out.println("iteration= " + i);
85       atomic {
86         doOneMove(land, gamer);
87       }
88       if((i&15) == 0 && id == 0) { //same as i%AGEUPDATETHRESHOLD
89         /* Update age of all trees in a Map */
90         atomic {
91           barr.updateAge(land, MAXAGE, ROW, COLUMN);
92         }
93       }
94       Barrier.enterBarrier(id,mytinfo,nthreads);
95     }
96   }
97
98   public static void main(String[] args) {
99     // Parse args get number of threads
100     RainForest tmprf = new RainForest();
101     RainForest.parseCmdLine(args, tmprf);
102     int numThreads= tmprf.numThreads;
103     threadinfo[] tinfo;
104     Barrier mybarr;
105
106     int[] mid = new int[8];
107     mid[0] = (128<<24)|(195<<16)|(136<<8)|162;//dc-1
108     mid[1] = (128<<24)|(195<<16)|(136<<8)|163;//dc-2
109     mid[2] = (128<<24)|(195<<16)|(136<<8)|164;//dc-3
110     mid[3] = (128<<24)|(195<<16)|(136<<8)|165;//dc-4
111     mid[4] = (128<<24)|(195<<16)|(136<<8)|166;//dc-5
112     mid[5] = (128<<24)|(195<<16)|(136<<8)|167;//dc-6
113     mid[6] = (128<<24)|(195<<16)|(136<<8)|168;//dc-7
114     mid[7] = (128<<24)|(195<<16)|(136<<8)|169;//dc-8
115
116
117     // Init land and place rocks in boundaries
118     GameMap[][] world;
119
120     atomic {
121       tinfo = global new threadinfo[numThreads];
122       for(int i=0; i<numThreads; i++) { 
123         tinfo[i] = global new threadinfo();
124       } 
125     }
126
127     atomic {
128       mybarr = global new Barrier(numThreads, tinfo);
129       world = global new GameMap[ROW][COLUMN];
130       int i, j;
131       for (i = 0; i < ROW; i++) {
132         for (j = 0; j < COLUMN; j++) {
133           world[i][j] = global new GameMap();
134           if (j == 0 || j == COLUMN-1) {
135             RockType r = global new RockType();
136             world[i][j].putRock(r);
137           }
138           if (i == 0 || i == ROW-1) {
139             RockType r = global new RockType();
140             world[i][j].putRock(r);
141           }
142         }
143       }
144     }
145
146     /* Set up threads */
147     RainForest[] rf;
148     atomic {
149       rf = global new RainForest[numThreads];
150       for(int i=0; i<numThreads; i++) {
151         rf[i] = global new RainForest(world, mybarr, i, numThreads);
152       }
153     }
154
155     /* Start threads */
156     RainForest tmp;
157     for(int i = 0; i<numThreads; i++) {
158       atomic {
159         tmp = rf[i];
160       }
161       tmp.start(mid[i]);
162     }
163
164     /* Join threads */
165     for(int i = 0; i<numThreads; i++) {
166       atomic {
167         tmp = rf[i];
168       }
169       tmp.join();
170     }
171     System.printString("Finished\n");
172   }
173
174   public void doOneMove(GameMap[][] land, Player gamer) {
175     // 1. Get start(x, y) position of the player
176     int currx = gamer.getX();
177     int curry = gamer.getY();
178
179     /* printLand(land, ROW, COLUMN); */
180
181     // 2. Get type of player (lumberjack or planter)
182     int type = gamer.kind();
183
184     /* gamer.debugPlayer(); */
185     //3. Change states
186     if (gamer.getState() == INIT) {
187       if (gamer.findGoal(land) < 0) {
188         gamer.reset(land, ROW, COLUMN, BLOCK);
189         return;
190       }
191       gamer.setState(MOVING);
192     } 
193
194     if (gamer.getState() == MOVING) {
195       Goal nextmove = new Goal();
196       int maxSearchDistance = 10;
197       boolean allowDiagMovement = true;
198       /* Find shortest path using AStar algo from start to goal */
199       AStarPathFinder apath =  new  AStarPathFinder(land, maxSearchDistance, allowDiagMovement, ROW, COLUMN);
200       Path newpath = apath.findPath(gamer);
201
202       /* Reset state if there in no path from start to goal */
203       if(newpath == null) {
204         // 
205         // Debug
206         // System.println("Path from ("+currx+","+curry+") to ("+gamer.getGoalX()+","+gamer.getGoalY()+") is null");
207         //
208
209         gamer.reset(land, ROW, COLUMN, BLOCK);
210         gamer.setState(INIT);
211         return;
212       }
213
214       nextmove.setXY(newpath.getX(0), newpath.getY(0));
215       gamer.setPosition(nextmove.getX(), nextmove.getY());
216       currx = gamer.getX();
217       curry = gamer.getY();
218       if (gamer.atDest()) {
219         if (gamer.kind() == LUMBERJACK) {
220           //If tree present, cut 
221           if (land[currx][curry].hasTree()) {
222             land[currx][curry].cutTree();
223             //
224             // Debug
225             // System.println("Cut tree");
226             //
227           } 
228         } else { // PLANTER
229           // If empty, plant tree 
230           if (land[currx][curry].hasTree() == false) {
231             if(hasMoreTrees(land, currx, curry) == false) {
232               TreeType t = global new TreeType();
233               land[currx][curry].putTree(t);
234               //
235               // Debug
236               // System.println("Put tree");
237               //
238             }
239           } 
240         }
241         gamer.setNewPosition(currx, curry, ROW, COLUMN, BLOCK);
242         gamer.setState(INIT);
243       } else if(land[currx][curry].hasTree() && gamer.kind() == LUMBERJACK) { //Cut trees along the way
244         land[currx][curry].cutTree();
245         // 
246         // Debug
247         // System.println("Cut tree while moving");
248         //
249       }
250       // Not at destination - do nothing
251       return;
252     }
253   }
254
255   /**
256    ** Only for Debugging 
257    **/
258   public void printLand(GameMap[][] land, int row, int col) {
259     for (int i = 0; i < row; i++) {
260       for (int j = 0; j < col; j++) {
261         land[i][j].print();
262       }
263       System.println("");
264     }
265   }
266
267   /**
268    * Parse the command line options.
269    **/
270   public static void parseCmdLine(String args[], RainForest rf) {
271     int i = 0;
272     String arg;
273     while(i < args.length && args[i].startsWith("-")) {
274       arg = args[i++];
275       //check options
276       if(arg.equals("-N")) {
277         if(i < args.length) {
278           rf.numThreads = new Integer(args[i++]).intValue();
279         }
280       } else if(arg.equals("-h")) {
281         rf.usage();
282       }
283     }
284
285     if(rf.numThreads == 0)
286       rf.usage();
287   }
288
289   /**
290    * The usage routine which describes the program options.
291    **/
292   public void usage() {
293     System.println("usage: ./RainForestN.bin master -N <threads>\n");
294     System.printString("    -N the number of threads\n");
295     System.printString("    -h help with usage\n");
296   }
297
298   /**
299    ** Check the number of trees in a given area
300    ** @return true if area covered more than the zone for trees 
301    **/
302   public boolean hasMoreTrees(GameMap[][] land, int x, int y) {
303     int lowx = x - BLOCK;
304     int highx = x + BLOCK;
305     int lowy = y - BLOCK;
306     int highy = y + BLOCK;
307     // define new boundaries
308     if (lowx <= 0) 
309       lowx = 1;
310     if (lowy <= 0) 
311       lowy = 1;
312     if (highx >= ROW-1) 
313       highx = ROW-2;
314     if (highy >= COLUMN-1) 
315       highy = COLUMN-2;
316     int treeCount = 0;
317     int areaCount = 0;
318     for(int i = lowx; i < highx; i++) {
319       for(int j = lowy; j < highy; j++) {
320         if(land[i][j].tree != null) 
321           treeCount++;
322         areaCount++;
323       }
324     }
325     if(treeCount >= (TREE_ZONE * areaCount)) {
326       return true;
327     }
328     return false;
329   }
330 }