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.Color;
009 import java.awt.Graphics2D;
010 import java.awt.geom.Point2D;
011 import java.util.Random;
012
013 /**
014 * Agent having a behaviour described as a set of rules (classifiers).
015 * @author Benoit
016 *
017 */
018 public class AgentClassifier extends Agent {
019
020
021 /**
022 * The template used by the Agent for its behaviour
023 */
024 protected Template template;
025
026 /**
027 * Indicates whether or not a Visibility Circle should be used
028 */
029 protected boolean isDetectionLimited = false;
030
031 /**
032 * Size of the visibility circle
033 */
034 protected double DETECTION_DISTANCE = 150;
035
036 /**
037 * Last movement vector (for the computation of the inertia
038 */
039 protected Vector2D lastMovVector;
040
041 /**
042 * The behaviour of the Agent
043 */
044 protected ClassifierSet behaviour;
045
046 /**
047 * Creates an AgentClassifier randmoly placed inside the Arena
048 * @param gen
049 * @param a
050 * @param name
051 */
052 public AgentClassifier(Random gen, Arena a, String name) {
053 super(gen, a);
054 lastMovVector = new Vector2D();
055 setName(name);
056 }
057
058
059 /**
060 * Calculates the New Movement Vector according to the <code>behaviourToConsider</code>.
061 * This corresponds to the procedure "Guess New Position"
062 * @param behaviourToConsider
063 * @param arena
064 * @param others
065 * @param nbEntities
066 * @param g
067 * @param actionSetToReturn
068 * @return
069 */
070 public Vector2D getNewMovVectorAccordingTo(
071 ClassifierSet behaviourToConsider,
072 Arena arena,
073 Entity[] others,
074 int nbEntities,
075 Graphics2D g,
076 ClassifierSet actionSetToReturn) {
077
078 Vector2D sumForces = new Vector2D();
079 Vector2D currentVector;
080
081 /* Putting all the entities together: adding the arena */
082 Entity[] en = new Entity[nbEntities + 1];
083 for (int i = 0; i < nbEntities; i++) {
084 en[i] = others[i];
085 }
086 en[nbEntities] = arena;
087
088 /* Adding the response to the other entities*/
089 for (int i = 0; i < nbEntities + 1; i++) {
090 Entity current = en[i];
091 Vector2D action = new Vector2D();
092 if (current.getId() != this.getId()
093 && this.canDetect(current)) // OTHER agents
094 {
095 /* get the definition of this agent */
096 String s = getTemplate().testCondition(current);
097 /* find the classifiers satisfied */
098 ClassifierSet matchSet = behaviourToConsider.getMatchSet(s);
099 if (Config.PRINT_MODE > 7) {
100 System.out.flush();
101 System.out.println(
102 "-- Size MatchSet for "
103 + s
104 + " :"
105 + matchSet.getSize());
106 System.out.flush();
107 }
108
109 /* from these, do a selection according to the template */
110 ClassifierSet actionSet = matchSet.getActionSet();
111 /* calculate the vector generated by the action parts of
112 * the classifiers selected
113 */
114 if (Config.PRINT_MODE > 7) {
115 System.out.flush();
116 System.out.println(
117 "-- Action Set for:"
118 + s
119 + " : size "
120 + actionSet.getSize());
121 System.out.println(actionSet.toString());
122 System.out.flush();
123 }
124 Classifier[] actionSetArray = actionSet.getClassifiers();
125 currentVector =
126 getTemplate().getVectorFromActions(
127 actionSetArray,
128 this,
129 current);
130 if (Config.PRINT_MODE > 8)
131 System.out.println(
132 "Reaction to:" + current + " - " + currentVector);
133 action.add(currentVector);
134 // adding the activated classifiers to the action Set
135 if(actionSetToReturn != null)
136 actionSetToReturn.addClassifierSet(actionSet);
137 }
138 sumForces.add(action);
139 }
140
141 // TODO limitate the speed
142
143 //TODO apply the momentum to represent the inertia
144 Vector2D movVector = new Vector2D(sumForces);
145 Vector2D inertia = new Vector2D(lastMovVector);
146 inertia.multiplyByConstant(0.1);
147 movVector.add(inertia);
148
149 //MovVector.multiplyByConstant(0.2); // iteration step
150
151 //Saving the new Movement Vector to use it for intertia next time
152 // MovVector.paint(getCoord(),g,Color.BLACK);
153 //System.out.println("FINAL-"+MovVector);
154 return movVector;
155
156 }
157
158
159 /**
160 * Move the agent according to its behaviour and the others entities around.
161 */
162 public void move(
163 Arena arena,
164 Entity[] others,
165 int nbEntities,
166 Graphics2D g) {
167 double newX = coord.getX();
168 double newY = coord.getY();
169
170 Vector2D newMovVector =
171 getNewMovVectorAccordingTo(
172 behaviour,
173 arena,
174 others,
175 nbEntities,
176 g,
177 null);
178
179 // newMovVector = Vector2D.getCorrectedVector(newMovVector,arena,this,g);
180
181 lastMovVector = newMovVector;
182
183
184 newX = newX + newMovVector.getX();
185 newY = newY + newMovVector.getY();
186
187 coord.setLocation(newX, newY);
188 }
189
190 /**
191 * Indicates if an Entity can be detected (inside the Visibility Circle).
192 * @param e the Entity to detect
193 * @return always true without a Visibility Circle; with a VC, true if e can be detected.
194 */
195 public boolean canDetect(Entity e) {
196 boolean result;
197 if (isDetectionLimited) {
198 // is the other agent visible ? (not too far)
199 result =
200 (this.distanceTo(e.getCoordNearTo(this)) < DETECTION_DISTANCE);
201
202 } else {
203 // always visible
204 result = true;
205 }
206
207 return result;
208 }
209
210 /**
211 * Draw the Circle around the Agent
212 * @param g
213 * @param coord
214 * @param c
215 */
216 protected void drawVisibilityCircle(Graphics2D g, Point2D coord, Color c) {
217 g.setColor(c);
218 int x = (int) (coord.getX() - (DETECTION_DISTANCE));
219 int y = (int) (coord.getY() - (DETECTION_DISTANCE));
220 g.drawOval(
221 x,
222 y,
223 (int) DETECTION_DISTANCE * 2,
224 (int) DETECTION_DISTANCE * 2);
225 }
226
227 /**
228 * Paint the Agent Classifier + its circle if it has one.
229 */
230 public void paint(Graphics2D g) {
231
232 // erase and draw the new visibility circle
233 if (isDetectionLimited) {
234 drawVisibilityCircle(g, oldcoord, Color.WHITE);
235 drawVisibilityCircle(g, coord, color_ext);
236 }
237 // draw the agent
238 super.paint(g);
239 }
240
241
242 public ClassifierSet getBehaviour() {
243 return behaviour;
244 }
245
246
247 public Vector2D getLastMovVector() {
248 return lastMovVector;
249 }
250
251
252 public Template getTemplate() {
253 return template;
254 }
255
256
257 public void setBehaviour(ClassifierSet behaviour) {
258 this.behaviour = behaviour;
259 }
260
261
262 public void setLastMovVector(Vector2D lastMovVector) {
263 this.lastMovVector = lastMovVector;
264 }
265
266
267 public void setTemplate(Template template) {
268 this.template = template;
269 }
270
271
272 public boolean isDetectionLimited() {
273 return isDetectionLimited;
274 }
275
276
277 public void setDetectionLimited(boolean b) {
278 isDetectionLimited = b;
279 }
280
281 }