int sx = gamer.getX();
int sy = gamer.getY();
+ int type = gamer.kind();
+
// easy first check, if the destination is blocked, we can't get there
- if(land[tx][ty].hasTree() || land[tx][ty].hasRock()) {
- return null;
+
+ if(type == 1) { //1 => PLANTER
+ if(land[tx][ty].hasTree() || land[tx][ty].hasRock()) {
+ return null;
+ }
+ } else { //LUMBERJACK
+ if((!land[tx][ty].hasTree()) || land[tx][ty].hasRock()) {
+ return null;
+ }
}
// initial state for A*. The closed group is empty. Only the starting
int xp = x + current.x;
int yp = y + current.y;
- if (isValidLocation(sx,sy,xp,yp)) {
+ if (isValidLocation(gamer,sx,sy,xp,yp)) {
// the cost to get to this node is cost the current plus the movement
// cost to reach this node. Note that the heursitic value is only used
// in the sorted open list
/**
** 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
**/
- public boolean isValidLocation(int sx, int sy, int xp, int yp) {
+ public boolean isValidLocation(Player gamer, int sx, int sy, int xp, int yp) {
boolean invalid = (xp <= 0) || (yp <= 0) || (xp >= rows-1) || (yp >= columns-1);
if ((!invalid) && ((sx != xp) || (sy != yp))) {
- if (land[xp][yp].hasTree() || land[xp][yp].hasRock()) {
- invalid = true;
+ if(gamer.kind() == 1) { //1=> PLANTER
+ if (land[xp][yp].hasTree() || land[xp][yp].hasRock()) {
+ invalid = true;
+ }
+ } else { //LUMBERJACK
+ if (land[xp][yp].hasRock()) {
+ invalid = true;
+ }
}
}
return !invalid;
/**
** An object representing the entity in the game that
- ** is going to moving along the path. This allows us to pass around entity/state
+ ** is going to move along the path. This allows us to pass around entity/state
** information to determine whether a particular tile is blocked, or how much
** cost to apply on a particular tile.
**
private int type;
private int x;
private int y;
- private int id;
private int lowx, highx;
private int lowy, highy;
private int state;
private int goalx, goaly;
+ private int rows, cols;
+ private Random rand;
public Player(int type, int x, int y) {
this.type = type;
this.x = x;
this.y = y;
- id = -1;
}
- public Player(int type, int x, int y, int id, int rows, int cols, int bounds) {
+ public Player(int type, int x, int y, int rows, int cols, int bounds) {
this.type = type;
this.x = x;
this.y = y;
- this.id = id;
+ this.rows = rows;
+ this.cols = cols;
lowx = x - bounds;
highx = x + bounds;
lowy = y - bounds;
highx = rows-2;
if (highy >= cols)
highy = cols-2;
+ rand = new Random(30); //seed to generate random numbers
}
- public void reset(int row, int col, int bounds) {
- int seed = x + y;
- Random rand = new Random(seed);
- x = (rand.nextInt(Math.abs(row - 2) + 1)) + 1;
- y = (rand.nextInt(Math.abs(col - 2) + 1)) + 1;
- goalx = -1;
- goaly = -1;
- setBoundary(bounds, row, col);
+ public void reset(GameMap[][] land, int row, int col, int bounds) {
+ //Teleport to new location
+ if(type == 1) { //PLANTER
+ x = (rand.nextInt(Math.abs(row - 2) + 1)) + 1;
+ y = (rand.nextInt(Math.abs(col - 2) + 1)) + 1;
+ goalx = -1;
+ goaly = -1;
+ setBoundary(bounds, row, col);
+ }
+
+ if(type == 0) { //LUMBERJACK
+ int trycount = 5; //try a few more times before teleporting
+ int i = 0;
+ while(i<trycount) {
+ int locx = (rand.nextInt(Math.abs(row - 2) + 1)) + 1;
+ int locy = (rand.nextInt(Math.abs(col - 2) + 1)) + 1;
+ if(!land[locx][locy].hasRock() && land[locx][locy].hasTree()) {
+ goalx = locx;
+ goaly = locy;
+ state = 1; //1=> MOVING state
+ return;
+ }
+ i++;
+ }
+ x = (rand.nextInt(Math.abs(row - 2) + 1)) + 1;
+ y = (rand.nextInt(Math.abs(col - 2) + 1)) + 1;
+ goalx = -1;
+ goaly = -1;
+ setBoundary(bounds, row, col);
+ }
}
public void setBoundary(int bounds, int rows, int cols) {
**/
public int findGoal(GameMap[][] land) {
/* Try setting the goal for try count times
- * if not possible , then select a completely new goal
+ * if not possible, then select a completely new goal
*/
int trycount = (highx - lowx) + (highy - lowy);
int i;
+ Random rand = new Random(0);
for (i = 0; i < trycount; i++) {
- Random rand = new Random(i);
int row = (rand.nextInt(Math.abs(highx - lowx)) + 1) + lowx;
int col = (rand.nextInt(Math.abs(highy - lowy)) + 1) + lowy;
if (type == 1 && (land[row][col].hasTree() == false) && (land[row][col].hasRock() == false)) {
return 0;
}
}
- if (i == trycount) {
- /* System.println("Timeout trying ... \n") Only for Debugging */
- }
return -1;
}
** Only for debugging
**/
public debugPlayer() {
- System.println("State= "+ state+ " Curr X= "+ x + " Curr Y= " + y + " Goal X= "+ goalx + " Goal Y= "+ goaly + " Type = " + type + "\n");
+ System.println("State= "+ state+ " Curr X= "+ x + " Curr Y= " + y + " Goal X= "+ goalx + " Goal Y= "+ goaly + " Type = " + type);
}
/**
-#define ROW 7 /* columns in the map */
-#define COLUMN 7 /* rows of in the map */
-#define ROUNDS 20 /* Number of moves by each player */
+#define ROW 100 /* columns in the map */
+#define COLUMN 100 /* rows of in the map */
+#define ROUNDS 256 /* Number of moves by each player */
#define PLAYERS 20 /* Number of Players when num Players != num of client machines */
#define RATI0 0.5 /* Number of lumberjacks to number of planters */
#define BLOCK 3 /* Area around the gamer to consider */
#define TREE_ZONE 0.4 /* Max percentage of trees in a zone */
-#define AGEUPDATETHRESHOLD 2 /* How frequently/how many rounds to increment age of tree */
+#define AGEUPDATETHRESHOLD 10 /* How frequently/how many rounds to increment age of tree */
#define MAXAGE 100 /* Max age of a tree */
**/
GameMap[][] land;
- /**
- * The gamer per thread: shared array where players do not see each other
- **/
- Player gamer;
-
/**
** The shared BarrierServer object updated when trees increment age
** only updated by one thread running server
}
- public RainForest(GameMap[][] land, Player gamer, BarrierServer barrserver, int threadid, int numThreads) {
+ public RainForest(GameMap[][] land, BarrierServer barrserver, int threadid, int numThreads) {
this.land = land;
- this.gamer = gamer;
this.threadid = threadid;
this.barrserver = barrserver;
this.numThreads = numThreads;
}
public void run() {
- //Do N rounds
- //do one move per round and synchronise
+ //Barrier for synchronizing moves
Barrier barr;
int id;
atomic {
id = threadid;
}
barr = new Barrier("128.195.136.162");
+
+ Random rand = new Random(id);
+ // Generate random numbers between 1 and row index/column index
+ int maxValue = ROW - 1;
+ int minValue = 1;
+ int row = (rand.nextInt(Math.abs(maxValue - minValue) + 1)) + minValue;
+ maxValue = COLUMN -1;
+ int col = (rand.nextInt(Math.abs(maxValue - minValue) + 1)) + minValue;
+ int person;
+ if((id&1) == 0) { //same as id%2
+ person = LUMBERJACK;
+ } else {
+ person = PLANTER;
+ }
+ Player gamer = new Player(person, row, col, ROW, COLUMN, BLOCK);
+
+ //Do N rounds
+ //do one move per round and synchronise
for(int i = 0; i<ROUNDS; i++) {
atomic {
doOneMove(land, gamer);
}
Barrier.enterBarrier(barr);
- if((i%AGEUPDATETHRESHOLD) == 0 && id == 0) {
+ if((i&15) == 0 && id == 0) { //same as i%AGEUPDATETHRESHOLD
/* Update age of all trees in a Map */
atomic {
barrserver.updateAge(land, MAXAGE, ROW, COLUMN);
mybarr.start(mid[0]);
- // Create P players
- // For each thread, init either a lumberjack/planter
- Player[] players;
- atomic {
- players = global new Player[numThreads];
- for (int i = 0; i < numThreads; i++) {
- Random rand = new Random(i);
- /* Generate random numbers between 1 and row index/column index*/
- int maxValue = ROW - 1;
- int minValue = 1;
- int row = (rand.nextInt(Math.abs(maxValue - minValue) + 1)) + minValue;
- maxValue = COLUMN -1;
- int col = (rand.nextInt(Math.abs(maxValue - minValue) + 1)) + minValue;
- int type = rand.nextInt(2);
- int person;
- if (type == 0) {
- person = LUMBERJACK;
- } else {
- person = PLANTER;
- }
- players[i] = global new Player(person, row, col, i, ROW, COLUMN, BLOCK);
- }
- }
-
/* Set up threads */
RainForest[] rf;
atomic {
rf = global new RainForest[numThreads];
for(int i=0; i<numThreads; i++) {
- Random rand = new Random(i);
- rf[i] = global new RainForest(world, players[i], mybarr, i, numThreads);
+ rf[i] = global new RainForest(world, mybarr, i, numThreads);
}
}
int currx = gamer.getX();
int curry = gamer.getY();
- // Only for Debugging
/* printLand(land, ROW, COLUMN); */
// 2. Get type of player (lumberjack or planter)
int type = gamer.kind();
+ /* gamer.debugPlayer(); */
+ //3. Change states
if (gamer.getState() == INIT) {
-
if (gamer.findGoal(land) < 0) {
- gamer.reset(ROW, COLUMN, BLOCK);
+ gamer.reset(land, ROW, COLUMN, BLOCK);
return;
}
gamer.setState(MOVING);
- /* gamer.debugPlayer(); Only for debugging */
}
if (gamer.getState() == MOVING) {
Goal nextmove = new Goal();
-
int maxSearchDistance = 10;
boolean allowDiagMovement = true;
+ /* Find shortest path using AStar algo from start to goal */
AStarPathFinder apath = new AStarPathFinder(land, maxSearchDistance, allowDiagMovement, ROW, COLUMN);
Path newpath = apath.findPath(gamer);
- /* Reset state if there in no path from src to destination */
+ /* Reset state if there in no path from start to goal */
if(newpath == null) {
- gamer.reset(ROW, COLUMN, BLOCK);
+ /* System.println("Path from ("+currx+","+curry+") to ("+gamer.getGoalX()+","+gamer.getGoalY()+") is null"); */
+ gamer.reset(land, ROW, COLUMN, BLOCK);
gamer.setState(INIT);
return;
}
if (land[currx][curry].hasTree()) {
land[currx][curry].cutTree();
}
- gamer.setNewPosition(currx, curry, ROW, COLUMN, BLOCK);
- gamer.setState(INIT);
} else { // PLANTER
// If empty, plant tree
if (land[currx][curry].hasTree() == false) {
land[currx][curry].putTree(t);
}
}
- gamer.setNewPosition(currx, curry, ROW, COLUMN, BLOCK);
- gamer.setState(INIT);
}
- }
+ gamer.setNewPosition(currx, curry, ROW, COLUMN, BLOCK);
+ gamer.setState(INIT);
+ } else if(land[currx][curry].hasTree() && gamer.kind() == LUMBERJACK) { //Cut trees along the way
+ land[currx][curry].cutTree();
+ }
// Not at destination - do nothing
- /* Debug -> gamer.debugPlayer(); */
return;
}
}