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

trafficsim.cpp

00001 /***************************************************************************
00002                         trafficsim.cpp  -  description
00003                              -------------------
00004     begin                : sam mai 01 2004
00005     copyright            : (C) 2003-2006 by Duong-Khang NGUYEN
00006     email                : neoneurone @ users sourceforge net
00007 
00008     $Id: trafficsim.cpp 79 2006-11-02 21:26:35Z neoneurone $
00009  ***************************************************************************/
00010 
00011 /***************************************************************************
00012  *                                                                         *
00013  *   This program is free software; you can redistribute it and/or modify  *
00014  *   it under the terms of the GNU General Public License as published by  *
00015  *   the Free Software Foundation; either version 2 of the License, or     *
00016  *   any later version.                                                    *
00017  *                                                                         *
00018  ***************************************************************************/
00019 
00020 #include "trafficsim.h"
00021 
00022 #include "buildinglayer.h"
00023 #include "../map.h"                 // We want our own map.h
00024 #include "pathstructure.h"
00025 
00026 #include "pathfinder.h"
00027 #include "movementmanager.h"
00028 #include "vehicle.h"
00029 
00030 
00031 
00032    /*=====================================================================*/
00033 TrafficSim::TrafficSim(
00034     SDL_mutex* mutex,
00035     BuildingLayer* pblayer,
00036     Map* pmap,
00037     PathFinder* pf,
00038     MovementManager* mm ):
00039 Simulator( mutex, pblayer, pmap ),
00040 ppf( pf ),
00041 pmm( mm )
00042 {
00043     OPENCITY_DEBUG( "TSim param ctor" );
00044 }
00045 
00046 
00047    /*=====================================================================*/
00048 TrafficSim::~TrafficSim()
00049 {
00050     OPENCITY_DEBUG( "TSim dtor" );
00051 }
00052 
00053 
00054    /*=====================================================================*/
00055 int
00056 TrafficSim::Main()
00057 {
00058     static uint w, h;
00059     static uint w1, h1, w2, h2;
00060     static uint startW, startH;
00061     static Structure* pstruct;
00062     static PathStructure* ppathstruct;
00063     static int iTrafficValue;
00064     static int iNumberPath;
00065 
00066 
00067     if (this->enumSimState == SIMULATOR_RUNNING) {
00068     // get a random road structure
00069         pstruct = pbuildlayer->GetRandomStructure(
00070             w, h, OC_STRUCTURE_ROAD );
00071 
00072         if (pstruct != NULL) {
00073         // try to lock the mutex
00074         // prevent the others from deleting the structure
00075         // pointed by "pstruct" while we're playing with
00076             SDL_LockMutex( this->mutexMain );
00077 
00078         // Save the starting point for pathfinding
00079             startW = w; startH = h;
00080 //debug
00081 //cout << "TrafficSim speaking: "
00082 //     << " / w: " << w << " / h: " << h;
00083         // Convert the pstruct to the correct structure
00084             ppathstruct = (PathStructure*)pstruct;
00085 
00086         // Get the surface around the structure we have
00087             w1 = w; h1 = h;
00088             this->pmapOfCity->GetPossibleWH(
00089                 w1, h1, -OC_P_RCIP_RANGE, -OC_P_RCIP_RANGE );
00090             w2 = w; h2 = h;
00091             this->pmapOfCity->GetPossibleWH(
00092                 w2, h2,  OC_P_RCIP_RANGE,  OC_P_RCIP_RANGE );
00093 
00094         // Calculate the traffic
00095             iTrafficValue = 0;
00096             iNumberPath = 0;    // this one is always > 0
00097             for ( w = w1; w <= w2; w++ ) {
00098                 for ( h = h1; h <= h2; h++ ) {
00099                 // we reuse the "pstruct" variable here
00100                     pstruct = pbuildlayer->GetStructure( w, h );
00101                     if (pstruct != NULL)
00102                     switch (pstruct->GetCode()) {
00103                         case OC_STRUCTURE_ROAD:
00104                             iNumberPath++;
00105                             break;
00106                         case OC_STRUCTURE_RES:
00107                         case OC_STRUCTURE_COM:
00108                         case OC_STRUCTURE_IND:
00109                             iTrafficValue += pstruct->GetLevel();
00110                             break;
00111 
00112                         default:
00113                         // keep gcc happy
00114                             break;
00115                     }
00116                 } // for h
00117             } // for w
00118 
00119         // Since "ubNumberPath" is always > 0
00120             iTrafficValue = iTrafficValue / iNumberPath;
00121 
00122         // give the current path structure the traffic value
00123         // it's always >= 0 since
00124         // since the structure's level is always >= 0
00125             ppathstruct->SetTraffic((OC_UBYTE)iTrafficValue );
00126 
00127 //debug
00128 //cout << " / Value: " << iTrafficValue << endl;
00129 
00130         // let the others run !
00131             SDL_UnlockMutex( this->mutexMain );
00132 
00133         // WARNING: the pathfinderShortestPath() need the unlocked mutex !
00134         // Are we going to create a new vehicle ?
00135             if ((iTrafficValue > OC_TSIM_TRAFFIC_MIN )
00136             &&  ( (rand() % 100) < OC_TSIM_VEHICLE_CHANCE )) {
00137                 trafficsimNewVehicle(startW, startH);
00138             }
00139 
00140 
00141         } // if (pstruct != NULL)
00142     }  // if running
00143 
00144     return 0;
00145 }
00146 
00147 
00148    /*=====================================================================*/
00149 void TrafficSim::trafficsimNewVehicle(
00150     const uint& w,
00151     const uint& h )
00152 {
00153     vector<Destination> vdest;
00154     PathStructure* pstruct;
00155     uint w2, h2;
00156     int iRandom;
00157     Vehicle* pvehicle;
00158 
00159 // try to get a destination
00160 // NOTE: here we are sure that GetRandomStructure() returns
00161 //       a PathStructure* or NULL
00162 //       That's why whe doesn't need to use dynamic_cast<>
00163     pstruct = (PathStructure*)pbuildlayer->GetRandomStructure(
00164         w2, h2, OC_STRUCTURE_ROAD );
00165 
00166 // is it ok ?
00167     if (pstruct != NULL) {
00168         iRandom = rand() % Vehicle::VEHICLE_NUMBER;
00169 
00170     // buses prefer short distance
00171         if ( iRandom == Vehicle::VEHICLE_BUS) {
00172             this->ppf->findShortestPath(
00173                 w, h, w2, h2,
00174                 vdest,
00175                 PathFinder::OC_DISTANCE );
00176         }
00177     // sport vehicle prefer less traffic
00178         else if ( (iRandom == Vehicle::VEHICLE_SPORT)
00179                || (iRandom == Vehicle::VEHICLE_STD) ) {
00180             this->ppf->findShortestPath(
00181                 w, h, w2, h2,
00182                 vdest,
00183                 PathFinder::OC_TRAFFIC );
00184         }
00185 
00186     // now create the new vehicle if a path was found
00187         if ( vdest.size() > 0 ) {
00188             pvehicle = new Vehicle((Vehicle::VEHICLE_TYPE)iRandom );
00189             pvehicle->SetPath( vdest ); // path init
00190             pvehicle->Start();              // vehicle init
00191             if (pmm->Add( pvehicle ) < 0) {
00192                 OPENCITY_DEBUG("MoveMgr full");
00193                 delete pvehicle;
00194             }
00195         }
00196     }
00197 }
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221 
00222 
00223 

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