/*
Copyright 2006 by Sean Luke and George Mason University
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package sim.app.socialsystem;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import sim.util.MutableInt3D;
public /*strictfp*/ class DecisionMaker implements java.io.Serializable
{
private Vector list=null;
public Hashtable lookupReflex = null;
/*there are 3 components for the left, right and error signal
*
*
*
*/
private MutableInt3D x0l;
private MutableInt3D x0r;
private MutableInt3D x0_error;
private MutableInt3D x1l;
private MutableInt3D x1r;
private MutableInt3D x1_error;
public int max_dist_int=2;
//there are 3 behaviours ordered as
public static final int B_AGENT=0;
public static final int B_FOOD=1;
public static final int B_AGENTFOOD=2;
private int neworientation;
private int hasFood=0;
public DecisionMaker()
{
list=new Vector();
lookupReflex=new Hashtable();
//init the signals
x0l=new MutableInt3D(0, 0, 0);
x0r=new MutableInt3D(0, 0, 0);
x0_error=new MutableInt3D(0, 0, 0);
x1l=new MutableInt3D(0, 0, 0);
x1r=new MutableInt3D(0, 0, 0);
x1_error=new MutableInt3D(0, 0, 0);
initLookupReflex();
}
//build a lookup reflex for the agent so that he knows
//what orientation to choose according to the error
public void initLookupReflex()
{
lookupReflex.put(new Integer(-3), new Integer(0));
lookupReflex.put(new Integer(-2), new Integer(1));
lookupReflex.put(new Integer(-1), new Integer(2));
lookupReflex.put(new Integer(0), new Integer(0));
lookupReflex.put(new Integer(1), new Integer(-2));
lookupReflex.put(new Integer(-2), new Integer(-1));
lookupReflex.put(new Integer(-3), new Integer(0));
}
//find the reaction give the error from the hashtable
public int getReaction(int deltaerror)
{
Integer temp=new Integer(0);
if(lookupReflex.containsKey(new Integer(deltaerror)))
temp=(Integer)lookupReflex.get(new Integer(deltaerror));
return temp.intValue();
}
public void setFood(boolean f)
{
hasFood=1;
}
public DecisionMaker(double w1,double w2,double w3)
{
this();
hasFood=0;
}
public void reset() {
list.clear();
x0l.setTo(0,0,0);
x0r.setTo(0,0,0);
x0_error.setTo(0,0,0);
x1l.setTo(0,0,0);
x1r.setTo(0,0,0);
x1_error.setTo(0,0,0);
hasFood=0;
}
public void addInfo( DecisionInfo di )
{
list.add(di);
}
public void computeError()
{
Enumeration e=list.elements();
DecisionInfo di=null;
while(e.hasMoreElements()){
di=(DecisionInfo)(e.nextElement());
switch(di.direction)
{
case DecisionInfo.LEFT:
if(di.isAgent && !di.isFood)
{ x0l.x+=di.intdistance;x1l.x+=di.intdistance;}
else if(!di.isAgent && di.isFood)
{x0l.y+=di.intdistance;x1l.y+=di.intdistance;}
else if(di.isAgent && di.isFood)
{x0l.z+=di.intdistance;x1l.z+=di.intdistance;}
break;
case DecisionInfo.RIGHT:
if(di.isAgent && !di.isFood)
{ x0r.x+=di.intdistance;x1r.x+=di.intdistance;}
else if(!di.isAgent && di.isFood)
{ x0r.y+=di.intdistance;x1r.y+=di.intdistance;}
else if(di.isAgent && di.isFood)
{ x0r.z+=di.intdistance;x1r.z+=di.intdistance;}
break;
default:
break;
}
}
//subtract component by component the left - right signals
x0_error=x0l.subtract(x0l, x0r);
x1_error=x1l.subtract(x1l, x1r);
//saturation();
}
public void computeTotalDecision(int orientation)
{
/* avoidance (+):
* obstacle on the left, turn clockwise=increase orientation
* obstacle on the right, turn anticlockwise=decrease orientation
* attraction for food (-):
* food point on the left, turn anticlockwise
* food point on the right, turn clockwise
* attraction for agent with food (-)
*/
neworientation=orientation+getReaction(x0_error.x);
if(hasFood==0)
neworientation=neworientation+getReaction(x0_error.y)+getReaction(x0_error.z);
if(neworientation<Agent.N)
neworientation=8+neworientation;
neworientation=neworientation%8;
System.out.println("O:"+orientation+"N:"+neworientation+"E:"+x0_error.y);
}
private void saturation()
{
if(x0_error.x>1)
x0_error.x=1;
else if(x0_error.x<-1)
x0_error.x=-1;
if(x0_error.y>1)
x0_error.y=1;
else if(x0_error.y<-1)
x0_error.y=-1;
if(x0_error.z>1)
x0_error.z=1;
else if(x0_error.z<-4)
x0_error.z=-1;
}
public int getNextOrientation()
{
return neworientation;
}
public MutableInt3D getX0Error()
{
return x0_error;
}
public MutableInt3D getX1Error()
{
return x1_error;
}
}