private MarsModel() {
// ...
// initial location of garbage
int garbage_count = random.nextInt(5);
for (int i = 0; i < garbage_count; i++) {
add(GARB, random.nextInt(GSize), random.nextInt(GSize));
}
// ...
}
private MarsModel() {
// ...
// initial location of r2
setAgPos(1, random.nextInt(GSize), random.nextInt(GSize));
// ...
}
private MarsModel() {
// ...
// initial location of r1
setAgPos(0, random.nextInt(GSize), random.nextInt(GSize));
// ...
}
class MarsModel extends GridWorldModel {
public static final int MErr = 2; // max error in pick garb
int nerr2; // Number of consecutive failures to burn the garbage
void burnGarb() {
// r2 location has garbage
if (hasObject(GARB, getAgPos(1))) {
// 50% chance to fail, until MErr attempts
if (random.nextBoolean() || nerr2 == MErr) {
remove(GARB, getAgPos(1));
nerr2 = 0;
} else {
nerr2++;
}
}
}
}
void nextSlot() throws Exception {
Location r1 = getAgPos(0);
// First increment y
r1.y++;
// If out of the bottom, go right, and start from the top again
if (r1.y == getHeight()) {
r1.y = 0;
r1.x++;
}
// When out of the right, start from the top left again
if (r1.x == getWidth()) {
r1.x = 0;
r1.y = 0;
}
setAgPos(0, r1);
// ...
}
For this task, we started with a copy of r1, and removed the part that makes it pick up the garbage, and move it to r2. This way, we are left with an agent that moves through the grid. Then, we changed its movement so that it is random, by implementing in Java mover(slot). Then, we added a place(garb) term, that adds garbage randomly where r3 is.
void moveRand() {
Location r3 = getAgPos(2);
int dx[] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {-1, 0, 1, -1, 1, -1, 0, 1};
while (true) {
int option = random.nextInt(dx.length);
int newx = r3.x + dx[option];
int newy = r3.y + dy[option];
if (newx >= 0 && newx < getWidth() && newy >= 0 && newy < getHeight()) {
r3.x = newx;
r3.y = newy;
break;
}
}
setAgPos(2, r3);
setAgPos(3, getAgPos(3)); // just to draw it in the view
setAgPos(1, getAgPos(1)); // just to draw it in the view
setAgPos(0, getAgPos(0)); // just to draw it in the view
}
void placeGarb() {
if (random.nextDouble() < 0.2) add(GARB, getAgPos(2));
}
We have added a R4 agent, that does the same as R1, but instead of following an order in the grid, it goes directly to the closest garbage. In order to do this, we copied R1, and changed the term 'nextSlot' so that it finds the closest garbage, and moves towards it.
void nextSlot4() throws Exception {
Location r4 = getAgPos(3);
Point r4p = new Point(r4.x, r4.y);
// A comparator to find the closest point to R4
Comparator<Point> comparator = new Comparator<Point>() {
public int compare(Point p1, Point p2) {
return (int)(p1.distanceSq(r4p) - p2.distanceSq(r4p));
}
};
// Scan the grid to find all the garbages
List<Point> garbages = new ArrayList<Point>();
for (int y = 0; y<getHeight(); y++) {
for (int x = 0; x<getWidth(); x++) {
if (model.hasObject(GARB, x, y)) {
garbages.add(new Point(x, y));
}
}
}
// If there is no garbage, do nothing
if (garbages.isEmpty()) return;
// Sort the garbages by increasing distance to R4
Collections.sort(garbages, comparator);
// Get the closest one
Point closestGarb = garbages.get(0);
// Move R4 towards that garbage
r4.x += Integer.signum(closestGarb.x - r4.x);
r4.y += Integer.signum(closestGarb.y - r4.y);
setAgPos(3, r4); // Set the position of R4
setAgPos(0, getAgPos(0)); // just to draw it in the view
setAgPos(1, getAgPos(1)); // just to draw it in the view
setAgPos(2, getAgPos(2)); // just to draw it in the view
}