00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "agentpolice.h"
00023 #include "kernel.h"
00024 #include "environment.h"
00025 #include "message.h"
00026 #include "destination.h"
00027
00028 #include <cstdlib>
00029
00030
00031 #define MAX_DISTANCE 200
00032 #define MAX_PERCEPTION_RANGE 10
00033
00034
00035
00036 AgentPolice::AgentPolice(Kernel& kernel, Environment& env, int x, int y):
00037 Agent(kernel, env, x, y, ROLE_POLICE),
00038 m_state( POLICE_LOOK )
00039 {
00040 m_sleep = 3;
00041 SetState( POLICE_LOOK );
00042
00043 this->born();
00044
00045
00046 this->SetGraphicCode( OC_VEHICLE_POLICE );
00047 }
00048
00049
00050
00051 AgentPolice::~AgentPolice()
00052 {
00053 if (m_agent_state != AGENT_DIE)
00054 this->die();
00055 }
00056
00057
00058
00059
00060 Agent* AgentPolice::SeeBadGuy(direction_t dir)
00061 {
00062 Agent* agent = lookForAgent(dir, MAX_PERCEPTION_RANGE);
00063 if (agent == NULL)
00064 return agent;
00065 if (agent->getRole() == ROLE_POLICE)
00066 return NULL;
00067 return agent;
00068 }
00069
00070
00071
00072 void AgentPolice::SetState(police_state_t state)
00073 {
00074 m_index = 0;
00075 m_path.clear();
00076
00077 if (state == m_state) return;
00078
00079 m_state = state;
00080 switch(m_state)
00081 {
00082 case POLICE_COLLABORATE:
00083 break;
00084 case POLICE_PURSUE:
00085 m_pursue = 0;
00086 break;
00087 case POLICE_LOST_PURSUE:
00088 m_lost_pursue = 0;
00089 break;
00090 default:
00091 break;
00092 }
00093 }
00094
00095
00096
00097 void AgentPolice::Look()
00098 {
00099 MAS_DEBUG( "(look)" );
00100
00101 Agent* agent = FindBadGuy();
00102 if (agent == NULL)
00103 {
00104 randomMove();
00105 return;
00106 }
00107 MAS_DEBUG( "Look -> Pursue agent " << agent->getId() );
00108
00109 moveDirection();
00110 NoticePursue(agent);
00111 SetState(POLICE_PURSUE);
00112 }
00113
00114
00115
00116 void AgentPolice::NoticePursue(Agent *agent)
00117 {
00118
00119 Message::Message_t msgt;
00120 switch (agent->getRole()) {
00121 case ROLE_DEMONSTRATOR: msgt = Message::MSG_NEW_DEMONSTRATOR; break;
00122 case ROLE_ROBBER: msgt = Message::MSG_NEW_ROBBER; break;
00123 default:
00124 break;
00125 }
00126 Message msg = Message(msgt, this) << agent->getX() << agent->getY();
00127 m_kernel.sendMessage( ROLE_POLICE, msg );
00128 }
00129
00130
00131
00132
00133 Agent* AgentPolice::IsNearBadGuy()
00134 {
00135 Agent *agent = m_environment.getAgentAt(m_x-1, m_y);
00136 if (agent != NULL) return agent;
00137 agent = m_environment.getAgentAt(m_x+1, m_y);
00138 if (agent != NULL) return agent;
00139 agent = m_environment.getAgentAt(m_x, m_y-1);
00140 if (agent != NULL) return agent;
00141 agent = m_environment.getAgentAt(m_x, m_y+1);
00142 if (agent != NULL) return agent;
00143 return NULL;
00144 }
00145
00146
00147 void AgentPolice::Pursue()
00148 {
00149 moveDirection();
00150 Agent *agent = SeeBadGuy(m_direction);
00151 if (agent != NULL) {
00152 MAS_DEBUG( *this << "(is pursuing agent " << agent->getId() << ")" );
00153 m_lost_pursue = 0;
00154
00155
00156 m_pursue++;
00157 if (1<m_pursue and (m_pursue % 5) == 0)
00158 {
00159 NoticePursue(agent);
00160 }
00161 return;
00162 }
00163 agent = FindBadGuy(false);
00164 if (agent == NULL) {
00165 MAS_DEBUG( "Pursue -> Lost pursue" );
00166
00167 SetState(POLICE_LOST_PURSUE);
00168 }
00169 }
00170
00171
00172
00173 Agent* AgentPolice::FindBadGuy(bool test_backward)
00174 {
00175 Agent *agent = SeeBadGuy(m_direction);
00176 if (agent != NULL) return agent;
00177
00178 direction_t dir;
00179 unsigned char rotate = randomBool();
00180 if (rotate)
00181 dir = rotateLeft(m_direction);
00182 else
00183 dir = rotateRight(m_direction);
00184 agent = SeeBadGuy(dir);
00185
00186 if (agent != NULL) {
00187 m_direction = dir;
00188 return agent;
00189 }
00190
00191 if (rotate)
00192 dir = rotateRight(m_direction);
00193 else
00194 dir = rotateLeft(m_direction);
00195 agent = SeeBadGuy(dir);
00196
00197 if (agent != NULL) {
00198 m_direction = dir;
00199 return agent;
00200 }
00201
00202 if (test_backward) {
00203 dir = rotate180(m_direction);
00204 agent = SeeBadGuy(dir);
00205 if (agent != NULL) {
00206 m_direction = dir;
00207 return agent;
00208 }
00209 }
00210 return NULL;
00211 }
00212
00213
00214
00215 void AgentPolice::LostPursue()
00216 {
00217 MAS_DEBUG( "(did lost agent)" );
00218
00219 Agent *agent = FindBadGuy();
00220 if (agent != NULL) {
00221 MAS_DEBUG( "Lost pursue -> Pursue " << agent->getId() );
00222
00223 moveDirection();
00224 NoticePursue(agent);
00225 SetState(POLICE_PURSUE);
00226 return;
00227 }
00228
00229 m_lost_pursue++;
00230 if (7 < m_lost_pursue) {
00231 MAS_DEBUG( "Lost pursue -> Look" );
00232
00233 SetState(POLICE_LOOK);
00234 }
00235 randomMove(30);
00236
00237 agent = FindBadGuy();
00238 if (agent != NULL) {
00239 MAS_DEBUG( "Lost pursue -> Pursue (after moving)" << agent->getId() );
00240
00241 NoticePursue(agent);
00242 SetState(POLICE_PURSUE);
00243 return;
00244 }
00245 }
00246
00247
00248
00249 void AgentPolice::processMessage()
00250 {
00251 static Message msg;
00252
00253
00254 while (!m_messages.empty()) {
00255 msg = m_messages.front();
00256 switch (msg.getType()) {
00257 case Message::MSG_NEW_DEMONSTRATOR:
00258
00259 if ((msg.getSender() != this) and (m_state == POLICE_LOST_PURSUE || m_state == POLICE_LOOK)) {
00260
00261 unsigned int ax = msg[0].getUInt();
00262 unsigned int ay = msg[1].getUInt();
00263 if (Environment::toSquareDistance(m_x, m_y, ax, ay) <= MAX_DISTANCE) {
00264 m_environment.findShortestPath(m_x, m_y, ax, ay, m_path);
00265 if (m_path.size() > 1) {
00266 MAS_DEBUG( "-> Collaborate (path size=" << m_path.size() << ")" );
00267
00268
00269 m_index = 1;
00270 SetState(POLICE_COLLABORATE);
00271 }
00272 else {
00273 m_path.clear();
00274 m_index = 0;
00275
00276 Agent* agent = FindBadGuy();
00277 if (agent != NULL) {
00278 MAS_DEBUG( "(collaborate) Pursue agent " << agent->getId() );
00279
00280 NoticePursue(agent);
00281 SetState(POLICE_PURSUE);
00282 }
00283 }
00284 }
00285 }
00286 break;
00287
00288 case Message::MSG_AGENT_DIE:
00289 m_agent_state = AGENT_DIE;
00290 break;
00291
00292 default:
00293 MAS_DEBUG( "Received unknown message" );
00294 }
00295 m_messages.pop_front();
00296 }
00297 }
00298
00299
00300
00301 void AgentPolice::born()
00302 {
00303 Agent::born();
00304 m_kernel.registerRole(this, ROLE_POLICE);
00305 m_agent_state = AGENT_LIVE;
00306 }
00307
00308
00309
00310 void AgentPolice::Collaborate()
00311 {
00312 Agent *agent = IsNearBadGuy();
00313 if (agent != NULL)
00314 {
00315
00316 randomMove(-1);
00317 SetState(POLICE_PURSUE);
00318 return;
00319 }
00320 MAS_DEBUG( "(collaborate)" );
00321
00322 followPath();
00323 }
00324
00325
00326
00327 void AgentPolice::live()
00328 {
00329 if (m_agent_state != AGENT_LIVE)
00330 return;
00331
00332 if (m_sleep != 0 and (m_kernel.getStep() % m_sleep) != 0)
00333 return;
00334
00335 processMessage();
00336
00337 switch (m_state) {
00338 case POLICE_LOOK:
00339 Look();
00340 break;
00341
00342 case POLICE_PURSUE:
00343 Pursue();
00344 break;
00345
00346 case POLICE_LOST_PURSUE:
00347 LostPursue();
00348 break;
00349
00350 case POLICE_COLLABORATE:
00351 Collaborate();
00352 break;
00353 }
00354 }
00355
00356
00357
00358 void AgentPolice::die()
00359 {
00360 processMessage();
00361 Agent::die();
00362 m_kernel.unregisterRole(this, this->getRole());
00363 }
00364
00365
00366
00367 void AgentPolice::output (std::ostream& os) const
00368 {
00369 os << "AgentPolice " << getId();
00370 }
00371
00372
00373
00374
00375
00376 void
00377 AgentPolice::followPath()
00378 {
00379 int x, y;
00380 bool ok = false;
00381
00382
00383 if (m_path[m_index]._uiTime) {
00384 x = m_path[m_index]._uiW;
00385 y = m_path[m_index]._uiL;
00386 if (canMove(x, y) and move(x, y)) {
00387 ok = true;
00388 }
00389 else {
00390 m_index = 0;
00391 m_path.clear();
00392
00393 Agent *agent = m_environment.getAgentAt(x,y);
00394 if (agent != NULL and agent->getRole() != ROLE_POLICE) {
00395 MAS_DEBUG( "Collaborate -> Pursue (blocked)" << agent->getId() );
00396
00397 NoticePursue(agent);
00398 SetState (POLICE_PURSUE);
00399 return;
00400 } else {
00401 randomMove();
00402 MAS_DEBUG( "Collaborate -> Look (abort)" << agent->getId() );
00403
00404 SetState (POLICE_LOOK);
00405 return;
00406 }
00407 }
00408 }
00409
00410 if (--m_path[m_index]._uiTime == 0) {
00411 if (++m_index >= m_path.size()) {
00412 Agent *agent = SeeBadGuy(m_direction);
00413 if (agent != NULL) {
00414 MAS_DEBUG( "Collaborate -> Pursue (path ended)" << agent->getId() );
00415
00416 NoticePursue(agent);
00417 SetState (POLICE_PURSUE);
00418 }
00419 else {
00420 MAS_DEBUG( "Collaborate -> Look (path ended)" << agent->getId() );
00421
00422 SetState (POLICE_LOOK);
00423 }
00424 }
00425 }
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459