00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "agent.h"
00023 #include "kernel.h"
00024 #include "environment.h"
00025 #include "message.h"
00026
00027 #include "structure.h"
00028
00029 #include <cassert>
00030
00031
00032 Agent::Agent(Kernel& kernel, Environment &env, int x, int y, Role_t role):
00033 m_kernel(kernel),
00034 m_environment(env),
00035 m_x(x),
00036 m_y(y),
00037 m_role(role),
00038 m_enumGC( OC_EMPTY ),
00039 m_id(kernel.getAgentUniqId())
00040 {
00041 MAS_DEBUG( "ctor " << *this );
00042
00043 m_move_speed = 1;
00044 m_direction = (direction_t)randomInt(0, 3);
00045 }
00046
00047
00048
00049 Agent::~Agent()
00050 {
00051 MAS_DEBUG( "dtor " << *this );
00052 }
00053
00054
00055
00056 Role_t Agent::getRole() const
00057 {
00058 return m_role;
00059 }
00060
00061
00062
00063 void Agent::receiveMessage(const Message& msg)
00064 {
00065 MAS_DEBUG( *this << " receive " << msg );
00066
00067 m_messages.push_back(msg);
00068 }
00069
00070
00071
00072 void Agent::processMessage()
00073 {
00074 }
00075
00076
00077
00078 void Agent::sendMessage(Role_t role, const Message& msg)
00079 {
00080 m_kernel.sendMessage(role, msg);
00081 }
00082
00083
00084
00085 void Agent::sendMessageToAgent(AgentID_t agent, const Message& msg)
00086 {
00087 m_kernel.sendMessageToAgent(agent, msg);
00088 }
00089
00090
00091
00092 Agent* Agent::lookForAgent(direction_t dir, unsigned long max_distance)
00093 {
00094 int x = m_x, y = m_y;
00095 int dx=0, dy=0;
00096 switch (dir)
00097 {
00098 case NORTH: dy = 1; break;
00099 case SOUTH: dy = -1; break;
00100 case EAST: dx = 1; break;
00101 case WEST: dx = -1; break;
00102 }
00103
00104 uint step;
00105 for (step=1; step<=max_distance; step++)
00106 {
00107 x += dx;
00108 y += dy;
00109 if (x < 0 || y < 0 || (int)m_environment.getWidth() <= x || (int)m_environment.getHeight() <= y)
00110 {
00111 break;
00112 }
00113 if (m_environment.hasAgentAt(this, x, y))
00114 {
00115 return m_environment.getAgentAt(x,y);
00116 }
00117 }
00118 return NULL;
00119 }
00120
00121
00122
00123 bool Agent::randomMove(int turn_percent)
00124 {
00125 bool ok = doRandomMove(turn_percent);
00126 if (ok)
00127 {
00128 ok = moveDirection();
00129
00130
00131
00132 }
00133 return ok;
00134 }
00135
00136
00137
00138 bool Agent::doRandomMove(int turn_percent)
00139 {
00140 bool ok = canMove(m_direction);
00141 if (ok) {
00142 if (turn_percent < randomInt(0,99))
00143 return true;
00144
00145
00146 direction_t dir;
00147 unsigned char rotate = randomBool();
00148 if (rotate)
00149 dir = rotateLeft(m_direction);
00150 else
00151 dir = rotateRight(m_direction);
00152 if (canMove(dir))
00153 {
00154 m_direction = dir;
00155 return true;
00156 }
00157
00158
00159 if (rotate)
00160 dir = rotateRight(m_direction);
00161 else
00162 dir = rotateLeft(m_direction);
00163 if (canMove(dir))
00164 m_direction = dir;
00165 return true;
00166 }
00167 else {
00168
00169 unsigned char rotate = randomBool();
00170 direction_t dir;
00171 if (rotate)
00172 dir = rotateLeft(m_direction);
00173 else
00174 dir = rotateRight(m_direction);
00175 if (canMove(dir))
00176 {
00177 m_direction = dir;
00178 return true;
00179 }
00180
00181
00182 if (rotate)
00183 dir = rotateRight(m_direction);
00184 else
00185 dir = rotateLeft(m_direction);
00186 if (canMove(dir))
00187 {
00188 m_direction = dir;
00189 return true;
00190 }
00191
00192
00193 if (rotate)
00194 m_direction = rotate180(m_direction);
00195 else
00196 m_direction = rotate180(m_direction);
00197 return canMove(m_direction);
00198 }
00199 }
00200
00201
00202
00203 void Agent::born()
00204 {
00205 m_agent_state = AGENT_BORN;
00206 m_kernel.registerAgent(this);
00207 m_environment.registerAgent(this, m_x, m_y);
00208 }
00209
00210
00211
00212 void Agent::live()
00213 {
00214 }
00215
00216
00217
00218 void Agent::die()
00219 {
00220 m_agent_state = AGENT_DIE;
00221 m_kernel.unregisterAgent(this);
00222 m_environment.unregisterAgent(this);
00223 }
00224
00225
00226
00227 AgentID_t Agent::getId() const
00228 {
00229 return m_id;
00230 }
00231
00232
00233
00234 unsigned int Agent::getX() const
00235 {
00236 return m_x;
00237 }
00238
00239
00240
00241 unsigned int Agent::getY() const
00242 {
00243 return m_y;
00244 }
00245
00246
00247
00248 void Agent::output (std::ostream& os) const
00249 {
00250 os << "Agent " << m_id;
00251 }
00252
00253
00254
00255 std::ostream& operator<< (std::ostream& os, const Agent &agent)
00256 {
00257 agent.output(os);
00258 return os;
00259 }
00260
00261
00262
00263 const OPENCITY_GRAPHIC_CODE
00264 Agent::GetGraphicCode() const
00265 {
00266 return m_enumGC;
00267 }
00268
00269
00270
00271 bool Agent::move(int x, int y)
00272 {
00273 assert (0 <= x && 0 <= y && x < (int)m_environment.getWidth() && y < (int)m_environment.getHeight());
00274 if (m_environment.moveAgent(this, x, y))
00275 {
00276 m_x = static_cast<unsigned int>(x);
00277 m_y = static_cast<unsigned int>(y);
00278 return true;
00279 } else {
00280 return false;
00281 }
00282 }
00283
00284
00285
00286 bool
00287 Agent::moveDirection()
00288 {
00289 int x, y;
00290 return (canMove(m_direction, x, y) and move(x,y));
00291 }
00292
00293
00294
00295 bool
00296 Agent::canMove(int x, int y) const
00297 {
00298 if ( x < 0
00299 or y < 0
00300 or (int)m_environment.getWidth() <= x
00301 or(int)m_environment.getHeight() <= y )
00302 return false;
00303
00304 Structure* building = m_environment.getBuildingXY(x, y);
00305 if (building == NULL)
00306 return false;
00307
00308 bool ok = building->GetCode() == OC_STRUCTURE_ROAD;
00309 if (ok) {
00310 ok = !m_environment.hasAgentAt(this, x, y);
00311 }
00312 return ok;
00313 }
00314
00315
00316
00317 bool
00318 Agent::canMove(direction_t dir) const
00319 {
00320 int x, y;
00321 return canMove(dir, x, y);
00322 }
00323
00324
00325
00326 bool
00327 Agent::canMove(direction_t dir, int &x, int &y) const
00328 {
00329 x = static_cast<int>(m_x);
00330 y = static_cast<int>(m_y);
00331 switch (dir) {
00332 case NORTH: y += m_move_speed; break;
00333 case SOUTH: y -= m_move_speed; break;
00334 case EAST: x += m_move_speed; break;
00335 case WEST: x -= m_move_speed; break;
00336 }
00337 return canMove(x, y);
00338 }
00339
00340
00341
00342 void
00343 Agent::SetGraphicCode( const OPENCITY_GRAPHIC_CODE gc )
00344 {
00345 m_enumGC = gc;
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373