@agent Resident {
@uses ; // We need this Swarm package
// as we are using lists here
@var: int color, age, maxAge;
@var: int posX, posY;
@var: float limit;
@sub: (void) setX: (int) x Y: (int) y {
posX = x;
posY = y;
[model->city putObject: self atX: posX Y: posY];
}
@sub: (void) setColor: (int) c maxAge: (int) a AndLimit: (float) l {
color = c;
age = 0;
maxAge = a;
limit = l;
}
@sub: (void) step {
int i, j, num, numOfOK, numOfEmpties;
float level;
Resident *dummy; // The neighbor under observation
id emptyX, emptyY; // List of possible locations to go
// (X and Y coordinates separately).
emptyX = [List create: [self getZone]];
emptyY = [List create: [self getZone]];
num = numOfOK = 0;
for (i=-1; i<2; i++)
for(j=-1; j<2; j++) {
// If the location is not ours
if ((i!=0) || (j!=0)) {
dummy = [model->city getObjectAtX:
((posX+i+model->citySize) % model->citySize)
Y:
((posY+j+model->citySize) % model->citySize)];
if (dummy != nil) {
num++;
if (dummy->color == color)
numOfOK++;
}
else { // otherwise do the statistics of emptyIsOK
if (model->emptyIsOK) {
numOfOK++;
num++;
}
// And append the location to the 'emptyLoc' list
[emptyX addFirst: (id) ((posX+i+model->citySize) % model->citySize)];
[emptyY addFirst: (id) ((posY+j+model->citySize) % model->citySize)];
}
}
}
// Calculating the current ratio
level = (float) numOfOK / (float) num;
numOfEmpties = [emptyX getCount];
// If we have to move and there is place to move to, let's move
if ((level < limit) && (numOfEmpties > 0) ) {
// If there is only 1 place, then we set it frankly
if (numOfEmpties == 1)
i = 0;
else // otherwise we select randomly
i = [uniformIntRand getIntegerWithMin: 0 withMax: (numOfEmpties-1)];
// Clear the current location, and set the new one
[model->city putObject: nil atX: posX Y: posY];
[self setX: (int) [emptyX atOffset: i]
Y: (int) [emptyY atOffset: i]
];
}
// Clear the lists
[emptyX removeAll];
[emptyY removeAll];
[emptyX drop];
[emptyY drop];
// Increment the age
age++;
// If its time to die, then do so.
// (That is, create a new resident at a random location).
if (age > maxAge) {
[model->city putObject: nil atX: posX Y: posY];
[model createNewResident: self];
}
}
}
Return to Contents of this issue
© Copyright Journal of Artificial Societies and Social Simulation, 1999