Hello Smart People,

I'm implementing an Ant Simulator (swarm search stuff) and I'd like to be able to load different "species" of Ants (.java classes that implement an Ant interface). I've been having trouble creating "num" of a certain species and initializing their initial position.

If num = x, then all of the x ants created have the xth Ant's cooridinates. It's as if I add the same object x times as opposed to creating x new objects and adding them to my vector.

I've tried three seperate things that should work, however none of them do. In the second attempt, I directly create and add a certain species (my "Explorer Ant"), and even this doesn't work.

I get the feeling that it's a very basic problem, but I'm not seeing anything clearly right now. What do you guys think?

while (i<num)
{
  try
  {	
	// Used for all attempts
	Dimension d = new Dimension(i, 100);
				
	// Attempt Eins
	Class c = Class.forName(species); //species is a string
	Class[] intArgsClass = new Class[]{Dimension.class};
	Object[] antArgs = {d};
	Constructor antConstructor =c.getConstructor(intArgsClass);
	Object object = null;
	object = antConstructor.newInstance(antArgs);
	Ant ant = (Ant) object;
	newAnts.addElement(ant);
				
	// Attempt Zwei
	newAnts2.addElement(new Explorer(d));
				
	// Attempt Drei
	Ant o = (Ant) c.newInstance();
	o.setLocation(d);
	newAnts3.addElement(o);
  } 
			
  catch (All Kinds of Crap e)
  {
	System.out.println(e);		
  }
			
  i++;
}

much love.
g.

You're thinking way too complex thoughts :)

/*
 * created: Sep 23, 2003
 * by: wtg
 */
package nl.wtg;

import java.util.Map;
import java.util.ResourceBundle;

/**
 * @author wtg
 */
public class HandlerFactory
{
	private static HandlerFactory instance = null;
	private static ResourceBundle handlers = null;

	private HandlerFactory()
	{
		handlers = ResourceBundle.getBundle("nl.wtg.handlers");		
	}
	
	public static void resetFactory()
	{
		handlers = null;
		instance = null;
	}

	/**
	 * retrieve the HandlerFactory
	 * @return the HandlerFactory
	 */
	public static synchronized HandlerFactory getInstance()
	{
		if (instance == null)
		{
			instance = new HandlerFactory();
		}
		return instance;
	}
	
	/**
	 * Retrieve a Handler. Add additional handler classes to resourcebundle<br /> 
	 * nl.wtg.handlers and restart application<br />
	 * All Handlers should derive directly or indirectly from <br />
	 * {@link nl.wtg.AbstractHandler AbstractHandler}
	 * @param handlerName name of the Handler to retrieve
	 * @param params further parameters to pass to the init function
	 * @return Handler Object of the correct type
	 */
	public AbstractHandler getHandler(String handlerName, Object params)
	{
		AbstractHandler h = null;
		try
		{
			h = (AbstractHandler)Class.forName(handlers.getString(handlerName)).newInstance();
		}
		catch (InstantiationException e)
		{
			throw new UnsupportedOperationException("unsupporter Handler " + handlerName + ": " + e.getMessage());
		}
		catch (IllegalAccessException e)
		{
			throw new UnsupportedOperationException("unsupporter Handler " + handlerName + ": " + e.getMessage());

		}
		catch (ClassNotFoundException e)
		{
			throw new UnsupportedOperationException("error instantiating Handler " + handlerName + ": " + e.getMessage());
		}
		h.init(params);
		return h;
	}
}
/*
 * created: Sep 26, 2003
 * by: wtg
 */
package nl.wtg;

import java.util.Map;

/**
 * @author wtg
 */
public abstract class AbstractHandler
{
	/**
	 * 
	 */
	public AbstractHandler()
	{
		super();
	}
	
	public abstract void init(Object params);

	public String toString()
	{
		return this.getClass().getName();
	}
		
}

AbstractHandler here would be replaced by an AbstractAnt from which all ants derive.
HandlerFactory would become an AntFactory.
Each ant class has an init method to set its fields (instead of having to rely on messy constructor calls using reflection.
The propertiesfile simply has lines for each type of ant like this

fireant=somepackage.FireAnt
forestant=somepackage.ForestAnt

By calling that factory in a loop for each ant you want created and adding the result to your collection you'll soon end up with an entire anthill.
To give better performance, create a single instance of the factory before entering the loop or make the factory a static method.

hmm.

Alright well, I don't know. Let's see, where do I begin?

So just so you know, I'm using an interface as opposed to an Abstract class. I've done away with the messy reflection business and tried to do some things similar to what you've done, but alas it's still not working.

public class Explorer implements Ant {
	
	public static int xLoc;
	public static int yLoc;
	public double evapConstant;
	public static boolean isDead;
	public String destination;
	
	public static Explorer instance = null;
	
	public Explorer()
	{
		// Initialize evapConstant, destination, etc.
	}
	
	public Ant getInstance()
	{
		if (instance == null)
		{
			instance = new Explorer();
		}	
		
		return instance;
		
	}

	public void setLocation(Dimension d)
	{
		xLoc = d.width;
		yLoc = d.height;
	}        

        ... Do Other Stuff...
}
while (i<num)
{
   try
   {					
	aunt = (Ant)Class.forName(species).newInstance();
   } 
			
  catch (Exception e)
  {
	System.out.println(e);
  }
 
  aunt .setLocation(d);
  newAnts.addElement(aunt );	
  i++;
}

When I do aunt .setLocaton(d), every Ant in my newAnts vector now has a location of d.

To be honest, I didn't really understand what you were telling me about :

fireant=somepackage.FireAnt
forestant=somepackage.ForestAnt

Anyway, thanks for the reply, I appreciate it. Any other ideas/clerifications are also appreciated.

peace.
g.

This article has been dead for over six months. Start a new discussion instead.