All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jadex.extension.envsupport.environment.space2d.Grid2D Maven / Gradle / Ivy

Go to download

The Jadex kernel extension envsupport allows for using 2D spaces in concert with components.

There is a newer version: 3.0.117
Show newest version
package jadex.extension.envsupport.environment.space2d;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import jadex.commons.collection.MultiCollection;
import jadex.extension.envsupport.environment.ISpaceObject;
import jadex.extension.envsupport.math.IVector1;
import jadex.extension.envsupport.math.IVector2;
import jadex.extension.envsupport.math.Vector1Double;
import jadex.extension.envsupport.math.Vector1Int;
import jadex.extension.envsupport.math.Vector2Int;

/**
 *  2D grid environment.
 */
public class Grid2D extends Space2D
{
	//-------- constants --------

	/** The default ID for this space. */
	public static final String DEFAULT_NAME = Grid2D.class.getName();
	
	/** The moore neighborhood. */
	public static final String NEIGHBORHOOD_MOORE = "moore";
	
	/** The von neumann neighborhood. */
	public static final String NEIGHBORHOOD_VON_NEUMANN = "von_neumann";

	/** The neighborhood property. */
	public static final String PROPERTY_NEIGHBORHOOD = "neighborhood";
	
	//-------- attributes --------
	
	/** All simobject id's accessible per position. */
	protected MultiCollection objectsygridpos;
	
	//-------- constructors --------
	
	/**
	 * Creates a new {@link ContinuousSpace2D} with the default name.
	 * 
	 * @param clockService the clock service
	 * @param timeCoefficient the time coefficient for time differences.
	 * @param areaSize the size of the 2D area
	 */
	public Grid2D()
	{
		this(null);
	}
	
	/**
	 * Creates a new {@link ContinuousSpace2D} with the default name.
	 * 
	 * @param actionexecutor executor for component actions
	 * @param areasize the size of the 2D area
	 */
	public Grid2D(IVector2 areasize)
	{
		this(DEFAULT_NAME, areasize);
	}
	
	/**
	 * Creates a new {@link ContinuousSpace2D} with a special ID.
	 * @param name the name of this space
	 * @param areasize the size of the 2D area
	 * @param actionexecutor executor for component actions
	 */
	public Grid2D(Object name, IVector2 areasize)
	{
		super(areasize==null? null: new Vector2Int(areasize.getXAsInteger(), areasize.getYAsInteger()));
		this.setProperty("name", name);	
		this.objectsygridpos = new MultiCollection();
	}
	
	//-------- grid specific methods --------
		
	/**
	 *  Set the area size.
	 *  @param areasize The area size.
	 */
	public void setAreaSize(IVector2 areasize)
	{
		synchronized(monitor)
		{
			this.areasize = areasize==null? null: new Vector2Int(areasize.getXAsInteger(), areasize.getYAsInteger());
		}
	}
	
	/**
	 *  Get the neighborhood.
	 *  @return Set the neighborhood.
	 */
	public String getNeighborhood()
	{
		return getPropertyNames().contains(PROPERTY_NEIGHBORHOOD)
			? (String)getProperty(PROPERTY_NEIGHBORHOOD)
			: NEIGHBORHOOD_VON_NEUMANN;
	}

	/**
	 * Get all SimObjects from a specific type at a specific grid position
	 */
	public Collection getSpaceObjectsByGridPosition(IVector2 position, Object type)
	{
		Collection ret = null;
		synchronized(monitor)
		{
			if(position!=null)
			{
				position = adjustPosition(position);
				IVector2 fieldpos = new Vector2Int(position.getXAsInteger(), position.getYAsInteger());
			
				Collection simobjs = objectsygridpos.getCollection(fieldpos);
				if(null == type)
				{
					ret = simobjs;
				}
				else
				{
					ArrayList tmp = new ArrayList();
					for(Iterator objs = simobjs.iterator(); objs.hasNext();)
					{
						ISpaceObject curobj = (ISpaceObject)objs.next();
						if(type.equals(curobj.getType()))
						{
							tmp.add(curobj);
						}
					}
					if(tmp.size()>0)
						ret = tmp;
				}
			}
//			System.out.println("getSpaceObs: "+position+" "+type+" "+ret+" "+simobjs);
			
		}
		return ret;
	}
		
	/**
	 *  Get an empty position in the grid.
	 *  @return Empty {@link IVector2} position.
	 */
	public IVector2 getEmptyGridPosition()
	{
		synchronized(monitor)
		{
			IVector2 ret = null;

			// Problem of efficiently finding an empty field
			// Enumerating all empty fields would cause big
			// memory consumption on big grids
			
			// first try n times random value 
			int n = 5;
			for(int i=0; i getNearGridObjects(IVector2 position, int range, String types[])
	{
		synchronized(monitor)
		{
			Set ret = new HashSet();
			
			int sizex = areasize.getXAsInteger();
			int sizey = areasize.getYAsInteger();
	
			int x = position.getXAsInteger();
			int y = position.getYAsInteger();
//			IVector2 pos = new Vector2Int(x, y);
			
			
			int minx = x - range >= 0 || getBorderMode().equals(BORDER_TORUS) ? x - range : 0;
			int maxx = x + range <= sizex || getBorderMode().equals(BORDER_TORUS) ? x + range : sizex;

			int miny = y - range >= 0 || getBorderMode().equals(BORDER_TORUS) ? y - range : 0;
			int maxy = y + range <= sizey || getBorderMode().equals(BORDER_TORUS) ? y + range : sizey;

			for(int i = minx; i <= maxx; i++)
			{
				for(int j = miny; j <= maxy; j++)
				{
					Vector2Int testpos = new Vector2Int((i + sizex) % sizex, (j + sizey) % sizey);

					Collection tmp = objectsygridpos.getCollection(testpos);
					if(tmp != null)
					{
						if(types==null)
						{
							ret.addAll(tmp);
						}
						else
						{
							for(Iterator it=tmp.iterator(); it.hasNext(); )
							{
								ISpaceObject obj = (ISpaceObject)it.next();
								for(int z = 0; zobject mapping, for fast operation.
	 *  @param position	The position.
	 *  @param distance	The distance.
	 *  @param type	The type (or null for all objects).
	 */
	public Set getNearObjects(IVector2 position, IVector1 distance, String type)
	{
		synchronized(monitor)
		{
			Set ret = new HashSet();
			
			int sizex = areasize.getXAsInteger();
			int sizey = areasize.getYAsInteger();
	
			int x = position.getXAsInteger();
			int y = position.getYAsInteger();
			IVector2 pos = new Vector2Int(x, y);
			
			int range = distance.getAsInteger();
			
			int minx = x - range >= 0 || getBorderMode().equals(BORDER_TORUS) ? x - range : 0;
			int maxx = x + range <= sizex || getBorderMode().equals(BORDER_TORUS) ? x + range : sizex;

			int miny = y - range >= 0 || getBorderMode().equals(BORDER_TORUS) ? y - range : 0;
			int maxy = y + range <= sizey || getBorderMode().equals(BORDER_TORUS) ? y + range : sizey;

			for(int i = minx; i <= maxx; i++)
			{
				for(int j = miny; j <= maxy; j++)
				{
					Vector2Int testpos = new Vector2Int((i + sizex) % sizex, (j + sizey) % sizey);
					if(!getDistance(testpos, pos).greater(distance))
					{
						Collection tmp = objectsygridpos.getCollection(testpos);
						if(tmp != null)
						{
							if(type==null)
							{
								ret.addAll(tmp);
							}
							else
							{
								for(Iterator it=tmp.iterator(); it.hasNext(); )
								{
									ISpaceObject obj = (ISpaceObject)it.next();
									if(obj.getType().equals(type))
										ret.add(obj);
								}
							}
						}
					}
				}
			}
			
			return ret;
		}
	}
	
	/**
	 * Retrieve all objects in the distance for a position
	 * @param position
	 * @param distance
	 * @return The near objects. 
	 * /
	public ISpaceObject[] getNearObjects(IVector2 position, IVector2 maxdist, String type)
	{
		synchronized(monitor)
		{
			Collection ret = new ArrayList();
			
			int sizex = areasize.getXAsInteger();
			int sizey = areasize.getYAsInteger();
	
			int x = position.getXAsInteger();
			int y = position.getYAsInteger();
			
			int rangex = maxdist.getXAsInteger();
			int rangey = maxdist.getYAsInteger();
	
			int minx = x - rangex >= 0 || getBorderMode().equals(BORDER_TORUS) ? x - rangex : 0;
			int maxx = x + rangex <= sizex || getBorderMode().equals(BORDER_TORUS) ? x + rangex : sizex;

			int miny = y - rangey >= 0 || getBorderMode().equals(BORDER_TORUS) ? y - rangey : 0;
			int maxy = y + rangey <= sizey || getBorderMode().equals(BORDER_TORUS) ? y + rangey : sizey;

			for (int i = minx; i <= maxx; i++)
			{
				for (int j = miny; j <= maxy; j++)
				{
					Collection tmp = objectsygridpos.getCollection(
							new Vector2Int((i + sizex) % sizex, (j + sizey) % sizey));
					if(tmp != null)
					{
						if(type==null)
						{
							ret.addAll(tmp);
						}
						else
						{
							for(Iterator it=tmp.iterator(); it.hasNext(); )
							{
								ISpaceObject	obj	= (ISpaceObject)it.next();
								if(obj.getType().equals(type))
									ret.add(obj);
							}
						}
					}
				}
			}
			
			return(ISpaceObject[])ret.toArray(new ISpaceObject[ret.size()]);
		}
	}*/
	
	/**
	 * Returns the nearest object to the given position within a
	 * maximum distance from the position.
	 * 
	 * @param position position the object should be nearest to
	 * @param maxdist maximum distance from the position, use null for unlimited distance
	 * @return nearest object's ID or null if none is found
	 * /
	// Todo: doesn't work and needs termination condition.
	public ISpaceObject getNearestObject(IVector2 position, IVector1 maxdist, String type)
	{
		
		synchronized(monitor)
		{
			int	cnt	= 0;
			ISpaceObject	ret = null;
			IVector1	retdist	= null;
			IVector2	testpos	= position.copy();
			IVector1	testdist	= getDistance(position, testpos);
			IVector1	mindist	= testdist;			
			
			System.out.println("Nearest object: "+testpos);
			if((maxdist==null || !testdist.greater(maxdist)) && (ret==null || testdist.less(retdist)))
			{
				Collection	tmp	= getSpaceObjectsByGridPosition(testpos, type);
				if(tmp!=null && !tmp.isEmpty())
				{
					ret	= (ISpaceObject)tmp.iterator().next();
					retdist	= testdist;
					System.out.println("Nearest object found "+cnt+" steps: "+retdist+", "+ret);
				}
			}
			cnt++;
			
			for(int i=1; (ret==null || retdist.greater(mindist)) && (maxdist==null || !mindist.greater(maxdist)); i++)
			{
				// Move left / right
				for(int j=0; j




© 2015 - 2024 Weber Informatics LLC | Privacy Policy