Back to the download page
// World for Artificial Termites.
// A simulation of termites which can move bits of wood around the world
// according to simple rules.
//
// Author Matthew Caryl
// Created 29.10.96
//
// Although under copywrite to the author (Matthew Caryl) this code can be copied and modified for non-commercial
// purposes as long as any derivatives contain this condition.
//
// Last modification: 2000-04-02 changed graphics Xavier Outhier
// Last modification: 2000-04-05 adding wheat and cheese Xavier Outhier
// Last modification: 2000-04-06 adding forbidden Xavier Outhier
// Last modification: 2000-05-07 splitted in two applet World, on engine, one
// applet for GUI X(avier Outhier)
package ArtificialTermites;
import java.awt.Event;
import java.awt.Graphics;
import java.util.Date;
import java.util.*;
import ADT.Queue;
import ADT.QueueEmpty;
/**
* World is the main class of the simulation for artificial life for anthill.
* Seconde line of documentation for World.
*
* @author Matthew Caryl
* @author Xavier Outhier
* @version 1.3
**/
//public final class World implements Runnable {
public final class World {
/**
* The queue of ants. Each ant is in its thread.
**/
private WorldApplet worldApplet;
private Queue termiteQueue;
private boolean[][] forbiddenWorld; // To constraint movement of ants
private boolean[][] thingWorld; // To avoid wood, wheat and cheese to be at the same place
private boolean[][] woodWorld;
private boolean[][] wheatWorld;
private boolean[][] cheeseWorld;
private int worldWidth;
private int worldHeight;
private int woodPercentage;
private int wheatPercentage;
private int cheesePercentage;
private int termitePercentage;
private boolean ready = false;
private long randomSeed = 0;
private Thread engineThread;
static int defaultWoodPercentage = 5;
static int defaultWheatPercentage = 5;
static int defaultCheesePercentage = 5;
static int defaultTermitePercentage = 1;
static int defaultWorldWidth = 64; // 32*10 = 320
static int defaultWorldHeight = 48; // 24*10 = 240
/**
* Set the background, objects, food and ants randomly on the payload.
*
* @param width width of logical payload
* @param wFactor factor of width between low logical level and graphical level
* @param height height of logical payload
* @param hFactor factor of height between low logical level and graphical level
* @param block should be 1, here for historical reasons
* @param wood percentage of wood
* @param wheat percentage of wheat
* @param cheese percentage of cheese
* @param termites percentage of ants
*
**/
void initialiseWorld(int width, int height,
int wood, int wheat, int cheese, int termites,
WorldApplet world) {
System.out.println("Debut de World::initialseWorld");
worldWidth = width;
worldHeight = height;
woodPercentage = wood;
cheesePercentage = cheese;
wheatPercentage = wheat;
termitePercentage = termites;
worldApplet = world;
Date date = new Date();
randomSeed = date.getTime();
ready = false;
if (worldWidth < 1)
worldWidth = defaultWorldWidth;
if (worldHeight < 1)
worldHeight = defaultWorldHeight;
if (woodPercentage < 0 || woodPercentage > 100)
woodPercentage = defaultWoodPercentage;
if (wheatPercentage < 0 || wheatPercentage > 100)
wheatPercentage = defaultWheatPercentage;
if (cheesePercentage < 0 || cheesePercentage > 100)
cheesePercentage = defaultCheesePercentage;
if (termitePercentage < 0 || termitePercentage > 100)
termitePercentage = defaultTermitePercentage;
thingWorld = new boolean[worldWidth][worldHeight];
// install first forbidden parts
forbiddenWorld = new boolean[worldWidth][worldHeight];
initialiseForbiddenWorld();
woodWorld = new boolean[worldWidth][worldHeight];
for (int i = worldWidth * worldHeight * woodPercentage / 100; i > 0; i--)
addWood();
wheatWorld = new boolean[worldWidth][worldHeight];
for (int i = worldWidth * worldHeight * woodPercentage / 100; i > 0; i--)
addWheat();
cheeseWorld = new boolean[worldWidth][worldHeight];
for (int i = worldWidth * worldHeight * woodPercentage / 100; i > 0; i--)
addCheese();
int termiteCount = worldWidth * worldHeight * termitePercentage / 100;
termiteQueue = new Queue();
for (int i = termiteCount; i > 0; i--)
addTermite();
ready = true;
System.out.println("Fin de World::initialseWorld");
}
private void initialiseForbiddenWorld() {
for (int x = worldWidth - 1; x >= 0; x--)
{
// left side
setForbiddenWorld(x,0);
// right side
setForbiddenWorld(x,worldHeight-1);
}
for (int x = (3*worldWidth)/4; x >= worldWidth/4; x--)
{
// vertical line of half worldWidth
setForbiddenWorld(x,worldHeight/2);
}
for (int y = worldHeight - 1; y >= 0; y--)
{
// top side
setForbiddenWorld(0,y);
// bottom side
setForbiddenWorld(worldWidth-1,y);
}
}
public void finalize() throws Throwable {
stop();
super.finalize();
}
public void start() {
if (engineThread == null) {
engineThread = new Thread("World");
engineThread.start();
}
}
public void stop() {
if (engineThread != null && engineThread.isAlive())
engineThread.stop();
engineThread = null;
}
public void run() {
System.out.println("Debut de World::run");
try {
while (true)
{
synchronized (termiteQueue) {
for (int i = termiteQueue.size(); i > 0; i--)
((Termite) termiteQueue.requeue()).tick();
}
}
}
catch (QueueEmpty e) {
// this just means there are no termites
}
System.out.println("Fin World::run");
}
int random(int range) {
randomSeed = randomSeed * 1103515245 + 12345;
return (int) ((randomSeed / 65535) % range);
}
boolean forbiddenAt(int x, int y) {
return forbiddenWorld[mod(x, worldWidth)][mod(y, worldHeight)];
}
boolean thingAt(int x, int y) {
return thingWorld[mod(x, worldWidth)][mod(y, worldHeight)];
}
boolean woodAt(int x, int y) {
return woodWorld[mod(x, worldWidth)][mod(y, worldHeight)];
}
boolean wheatAt(int x, int y) {
return wheatWorld[mod(x, worldWidth)][mod(y, worldHeight)];
}
boolean cheeseAt(int x, int y) {
return cheeseWorld[mod(x, worldWidth)][mod(y, worldHeight)];
}
int woodPercentage() {
return woodPercentage;
}
int wheatPercentage() {
return wheatPercentage;
}
int cheesePercentage() {
return cheesePercentage;
}
int termitePercentage() {
return termitePercentage;
}
int width() {
return worldWidth;
}
int height() {
return worldHeight;
}
void setForbiddenWorld(int x, int y) {
x = mod(x, worldWidth);
y = mod(y, worldHeight);
forbiddenWorld[x][y] = true;
thingWorld[x][y] = true;
}
void resetForbiddenWorld(int x, int y) {
x = mod(x, worldWidth);
y = mod(y, worldHeight);
forbiddenWorld[x][y] = false;
thingWorld[x][y] = false;
}
private void addWood() {
int x, y;
// find free space for wood
do {
x = random(worldWidth);
y = random(worldHeight);
} while (thingAt(x, y));
putWood(x, y);
}
private void addWheat() {
int x, y;
// find free space for wood
do {
x = random(worldWidth);
y = random(worldHeight);
} while (thingAt(x, y));
putWheat(x, y);
}
private void addCheese() {
int x, y;
// find free space for wood
do {
x = random(worldWidth);
y = random(worldHeight);
} while (thingAt(x, y));
putCheese(x, y);
}
private void addTermite() {
int x, y;
Termite t;
x = random(worldWidth);
y = random(worldHeight);
t = new Termite(this, worldApplet, x, y);
termiteQueue.enqueue(t);
}
void putWood(int x, int y) {
x = mod(x, worldWidth);
y = mod(y, worldHeight);
woodWorld[x][y] = true;
thingWorld[x][y] = true;
}
void getWood(int x, int y) {
x = mod(x, worldWidth);
y = mod(y, worldHeight);
woodWorld[x][y] = false;
thingWorld[x][y] = false;
}
void putWheat(int x, int y) {
x = mod(x, worldWidth);
y = mod(y, worldHeight);
wheatWorld[x][y] = true;
thingWorld[x][y] = true;
}
void getWheat(int x, int y) {
x = mod(x, worldWidth);
y = mod(y, worldHeight);
wheatWorld[x][y] = false;
thingWorld[x][y] = false;
}
void putCheese(int x, int y) {
x = mod(x, worldWidth);
y = mod(y, worldHeight);
cheeseWorld[x][y] = true;
thingWorld[x][y] = true;
}
void getCheese(int x, int y) {
x = mod(x, worldWidth);
y = mod(y, worldHeight);
cheeseWorld[x][y] = false;
thingWorld[x][y] = false;
}
static int mod(int x, int y) {
int m;
m = x % y;
if (m < 0)
return m + y;
else
return m;
}
public Queue getTermiteQueue() {
return termiteQueue;
}
public WorldApplet getWorldApplet() {
return worldApplet;
}
public boolean getReady() {
return ready;
}
}
Back to the download page