001    /*
002     * SimuCS - Simulator to use with Classifier Systems 
003     * MSc project - Oxford University 
004     * by Benoit Isaac - Summer 2005
005     */
006    
007    package simuLCS;
008    import java.awt.Graphics2D;
009    import java.awt.geom.Point2D;
010    import java.util.Random;
011    
012    /**
013     * Agent moving according to R. Vaughan's mathematical model.
014     * @author Benoit
015     * 
016     */
017    public class AgentDuck extends Agent {
018            
019            protected double k1 = 3000;
020            protected double k2 = 1000;
021            protected double k3 = 500;
022            protected double k4 = 8000;
023            protected double parameterL = 30;
024            
025            protected Vector2D lastMovVector ;
026            
027            public AgentDuck(Random gen, Arena a) {
028                    super(gen,a);           
029            }
030    
031            public AgentDuck(Random gen, Arena a, String name)
032            {       this(gen,a);
033                    lastMovVector = new Vector2D();
034                    setName(name);  
035            }
036            
037            /**
038             * Moves the Agent according to the equation giving the movement vector
039             */
040            public void move(Arena a, Entity[] others, int nbEntities, Graphics2D g)
041            {
042                    double newX = coord.getX() ;
043                    double newY = coord.getY() ;
044                    
045                    Vector2D sumForces = new Vector2D();
046                    
047                    // Terms (1) and (2) for other ducks, (4) for the sheepdog(s)
048                    for(int i=0;i<nbEntities;i++)
049                    {
050                            Point2D posAgent = others[i].getCoord();
051                            if((others[i].getId() != this.getId())) // OTHER agents
052                            {
053                                    Vector2D DA = new Vector2D();
054                                    // compute unit vector Duck-OtherAgent
055                                    DA.setUnitVector(getCoord(),posAgent);
056                                    //System.out.println("DA-"+DA);
057                                    double distToAgent= this.distanceTo(posAgent);
058                                    double distToAgentSq = distToAgent * distToAgent ;
059                                    if (distToAgentSq < 5)
060                                    {
061                                            distToAgentSq = 5;
062                                    }
063                                    
064                                    if(others[i] instanceof AgentDuck) 
065                                    {
066                                            // add  [k1/(|DDn+L|)²] * unit vector   
067                                            double tmp2 = distToAgent+parameterL ;
068                                            Vector2D Fattract = new Vector2D(DA);
069                                            Fattract.multiplyByConstant(k1/(tmp2*tmp2));
070                                            //Fattract.paint(getCoord(),g,Color.GREEN);
071                                            //System.out.println("Fattract-"+Fattract);
072                                            sumForces.add(Fattract);
073                                            
074                                            // add - [k2/(|DDn|)²] * unit vector
075                                            
076                                            Vector2D Frepulse = new Vector2D(DA);
077                                            Frepulse.multiplyByConstant(-k2/distToAgentSq);
078                                            //Frepulse.paint(getCoord(),g,Color.GREEN);
079                                            //System.out.println("Frepulse-"+Frepulse);
080                                            sumForces.add(Frepulse);
081                                    }
082                                    else if(others[i] instanceof AgentInteractive) 
083                                    {
084                                            // add - [k4/(|DR|)²] * unit vector
085                                            Vector2D FrepSheepdog = new Vector2D(DA);
086                                            FrepSheepdog.multiplyByConstant(-k4/distToAgentSq);
087                                            // FrepSheepdog.paint(getCoord(),g,Color.RED);
088                                            //System.out.println("FrepSheepdog-"+FrepSheepdog);
089                                            sumForces.add(FrepSheepdog);
090                                    }
091                                    
092                            }
093                    
094                    }
095                    
096                    // repelled by the walls of the arena IF NOT IN THE CENTER
097                    Point2D W = arena.closestPointTo(getCoord());
098                    if(W.getX() != 0.0 || W.getY() != 0.0)  // agent not in the center
099                    {
100                            Vector2D Fwall = new Vector2D();
101                            if(!arena.isInside(getCoord().getX(),getCoord().getY(), 1))
102                            {       /* agent going out of the arena, the vector should be in the opposite */
103                                    Fwall.setUnitVector(W,getCoord());
104                            }
105                            else
106                            {
107                                    Fwall.setUnitVector(getCoord(),W);
108                            }
109                            double distToWall = arena.distanceTo(getCoord());
110                            double k3tmp = k3 ;
111    //                      if(distToWall < 8)
112    //                      {       k3tmp = 10*k3;
113    //                      }
114                            Fwall.multiplyByConstant(-k3tmp/(distToWall*distToWall));
115                            // Fwall.paint(getCoord(),g,Color.BLUE);
116                            //System.out.println("Fwall-"+Fwall);
117                            sumForces.add(Fwall);
118                    }
119                    
120                    
121                    Vector2D MovVector = new Vector2D(sumForces);
122                    Vector2D inertia = new Vector2D(lastMovVector);
123                    inertia.multiplyByConstant(0.1);
124                    MovVector.add(inertia);
125                    
126                    //MovVector.multiplyByConstant(0.2); // iteration step
127                    
128                    //Saving the new Movement Vector to use it for intertia next time       
129                    lastMovVector = MovVector ;
130                    
131                    newX = newX + MovVector.getX();
132                    newY = newY + MovVector.getY();
133                    
134                    coord.setLocation(newX,newY);
135            }
136    
137    
138    
139    
140            
141            /**
142             * An agent duck is not dangerous, by convention.
143             */
144            public boolean isDangerous(){
145                    return false;
146            }
147    
148    }