Back to download page 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 download page Back to the download page