Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

agent.cpp

00001 /***************************************************************************
00002                         agent.cpp  -  description
00003                         -------------------
00004     begin                : nov 29th 2005
00005     copyright            : (C) 2005-2006 by Duong-Khang NGUYEN
00006     email                : neoneurone @ users sourceforge net
00007     author               : Victor STINNER
00008 
00009     $Id: agent.cpp 35 2006-08-16 20:50:25Z neoneurone $
00010 ***************************************************************************/
00011 
00012 /***************************************************************************
00013 *                                                                         *
00014 *   This program is free software; you can redistribute it and/or modify  *
00015 *   it under the terms of the GNU General Public License as published by  *
00016 *   the Free Software Foundation; either version 2 of the License, or     *
00017 *   any later version.                                                    *
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 ),               // OpenCity's specifics
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 // debug
00130 //      std::cerr << "Agent " << getId() << ", move to direction " << m_direction
00131 //          << " at x: " << x << " / y: " << y << std::endl;
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         // Try left/right
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         // Try right/left (the opposite)
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         // Try left/right
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         // Try right/left (the opposite)
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         // try turn backward
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 

Generated on Sat Nov 11 10:21:09 2006 for OpenCity by  doxygen 1.4.2