Back to index

gcompris  8.2.2
traffic.c
Go to the documentation of this file.
00001 /* gcompris - traffic.c
00002  *
00003  * Copyright (C) 2002 Bruno Coudoin
00004  *
00005  * Based on the original code from Geoff Reedy <vader21@imsa.edu>
00006  * Copyright (C) 2000 Geoff Reedy
00007  *
00008  *   This program is free software; you can redistribute it and/or modify
00009  *   it under the terms of the GNU General Public License as published by
00010  *   the Free Software Foundation; either version 2 of the License, or
00011  *   (at your option) any later version.
00012  *
00013  *   This program is distributed in the hope that it will be useful,
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *   GNU General Public License for more details.
00017  *
00018  *   You should have received a copy of the GNU General Public License
00019  *   along with this program; if not, write to the Free Software
00020  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  */
00022 
00023 #include <string.h>
00024 
00025 #include "traffic.h"
00026 
00027 #include "gcompris/gcompris.h"
00028 
00029 #define SOUNDLISTFILE PACKAGE
00030 
00031 #define DATAFILE "TrafficData"
00032 
00033 
00034 static GcomprisBoard  *gcomprisBoard = NULL;
00035 static gboolean      board_paused  = TRUE;
00036 
00037 static GnomeCanvasGroup *allcars         = NULL;
00038 
00039 #define OFSET_X 250
00040 #define OFSET_Y 128
00041 
00042 static void    start_board (GcomprisBoard *agcomprisBoard);
00043 static void    pause_board (gboolean pause);
00044 static void    end_board (void);
00045 static gboolean       is_our_board (GcomprisBoard *gcomprisBoard);
00046 static void    set_level (guint level);
00047 static int     gamewon;
00048 static void    game_won(void);
00049 static void    repeat(void);
00050 
00051 static GnomeCanvasGroup *boardRootItem = NULL;
00052 
00053 static GnomeCanvasItem      *traffic_create_item(GnomeCanvasGroup *parent);
00054 static void           traffic_destroy_all_items(void);
00055 static void           traffic_next_level(void);
00056 
00057 typedef struct _car car;
00058 typedef struct _jam jam;
00059 
00060 struct _car {
00061   guint x : 3;
00062   guint y : 3;
00063 #define CAR_ORIENT_NS       0
00064 #define CAR_ORIENT_EW       1
00065   guint orient : 1;
00066   guint goal : 1;
00067   guint size;
00068   guint color;
00069   gchar color_string[50];
00070   GnomeCanvasGroup *canvasgroup;
00071 };
00072 
00073 struct _jam {
00074   guint num_cars;
00075   guint card;
00076   guint level;
00077 #define MAX_NUMBER_OF_CARS 20
00078   car *cars[MAX_NUMBER_OF_CARS];
00079 };
00080 
00081 static int     car_cb(GnomeCanvasItem *item, GdkEvent *event, car *thiscar);
00082 gboolean       load_level(guint level, guint card);
00083 
00084 static jam     current_card  ={0,0,0,{NULL}};
00085 
00086 static void    draw_grid  (GnomeCanvasGroup *rootBorder);
00087 static gint    cars_from_strv(char *strv);
00088 
00089 /* Description of this plugin */
00090 static BoardPlugin menu_bp =
00091   {
00092     NULL,
00093     NULL,
00094     "A sliding block puzzle game",
00095     "",
00096     "Bruno Coudoin <bruno.coudoin@free.fr>",
00097     NULL,
00098     NULL,
00099     NULL,
00100     NULL,
00101     start_board,
00102     pause_board,
00103     end_board,
00104     is_our_board,
00105     NULL,
00106     NULL,
00107     set_level,
00108     NULL,
00109     repeat,
00110     NULL,
00111     NULL
00112   };
00113 
00114 /*
00115  * Main entry point mandatory for each Gcompris's game
00116  * ---------------------------------------------------
00117  *
00118  */
00119 
00120 GET_BPLUGIN_INFO(traffic)
00121 
00122 /*
00123  * in : boolean TRUE = PAUSE : FALSE = CONTINUE
00124  *
00125  */
00126 static void pause_board (gboolean pause)
00127 {
00128   if(gcomprisBoard==NULL)
00129     return;
00130 
00131   if(gamewon == TRUE && pause == FALSE) /* the game is won */
00132     {
00133       game_won();
00134     }
00135 
00136   board_paused = pause;
00137 }
00138 
00139 /*
00140  */
00141 static void start_board (GcomprisBoard *agcomprisBoard)
00142 {
00143   GdkPixbuf *pixmap = NULL;
00144   char *str;
00145 
00146   if(agcomprisBoard!=NULL)
00147     {
00148       gchar *img;
00149 
00150       gcomprisBoard=agcomprisBoard;
00151       gcomprisBoard->level=1;
00152       gcomprisBoard->maxlevel=8;
00153       gcomprisBoard->sublevel=1;
00154       gcomprisBoard->number_of_sublevel=5; /* Go to next level after this number of 'play' */
00155       gc_score_start(SCORESTYLE_NOTE,
00156                         gcomprisBoard->width - 220,
00157                         gcomprisBoard->height - 50,
00158                         gcomprisBoard->number_of_sublevel);
00159 
00160       str = gc_skin_image_get("button_reload.png");
00161       pixmap = gc_pixmap_load(str);
00162       g_free(str);
00163       if(pixmap) {
00164        gc_bar_set_repeat_icon(pixmap);
00165        gdk_pixbuf_unref(pixmap);
00166        gc_bar_set(GC_BAR_LEVEL|GC_BAR_REPEAT_ICON);
00167       } else {
00168        gc_bar_set(GC_BAR_LEVEL|GC_BAR_REPEAT);
00169       }
00170 
00171       img = gc_skin_image_get("traffic-bg.jpg");
00172       gc_set_background(gnome_canvas_root(gcomprisBoard->canvas),
00173                            img);
00174       g_free(img);
00175 
00176       traffic_next_level();
00177 
00178       gamewon = FALSE;
00179       pause_board(FALSE);
00180     }
00181 }
00182 /* ======================================= */
00183 static void end_board ()
00184 {
00185   if(gcomprisBoard!=NULL)
00186     {
00187       pause_board(TRUE);
00188       gc_score_end();
00189       traffic_destroy_all_items();
00190     }
00191   gcomprisBoard = NULL;
00192 }
00193 
00194 /* ======================================= */
00195 static void set_level (guint level)
00196 {
00197 
00198   if(gcomprisBoard!=NULL)
00199     {
00200       gcomprisBoard->level=level;
00201       gcomprisBoard->sublevel=1;
00202       traffic_next_level();
00203     }
00204 }
00205 /* ======================================= */
00206 static gboolean is_our_board (GcomprisBoard *gcomprisBoard)
00207 {
00208   if (gcomprisBoard)
00209     {
00210       if(g_strcasecmp(gcomprisBoard->type, "traffic")==0)
00211        {
00212          /* Set the plugin entry */
00213          gcomprisBoard->plugin=&menu_bp;
00214 
00215          return TRUE;
00216        }
00217     }
00218   return FALSE;
00219 }
00220 
00221 /*
00222  * Repeat let the user restart the current level
00223  *
00224  */
00225 static void repeat (){
00226 
00227   traffic_destroy_all_items();
00228 
00229   /* Try the next level */
00230   traffic_create_item(gnome_canvas_root(gcomprisBoard->canvas));
00231 }
00232 
00233 /*-------------------------------------------------------------------------------*/
00234 /*-------------------------------------------------------------------------------*/
00235 /* set initial values for the next level */
00236 static void traffic_next_level()
00237 {
00238 
00239   gc_bar_set_level(gcomprisBoard);
00240 
00241   traffic_destroy_all_items();
00242   gamewon = FALSE;
00243 
00244   gc_score_set(gcomprisBoard->sublevel);
00245 
00246   /* Try the next level */
00247   traffic_create_item(gnome_canvas_root(gcomprisBoard->canvas));
00248 
00249 }
00250 /* ==================================== */
00251 /* Destroy all the items */
00252 static void traffic_destroy_all_items()
00253 {
00254   guint i;
00255 
00256   if(boardRootItem!=NULL)
00257     gtk_object_destroy (GTK_OBJECT(boardRootItem));
00258   boardRootItem = NULL;
00259 
00260   for (i=0; i<current_card.num_cars; i++)
00261     {
00262       g_free(current_card.cars[i]);
00263     }
00264   current_card.num_cars = 0;
00265 }
00266 
00267 /* ==================================== */
00268 static GnomeCanvasItem *traffic_create_item(GnomeCanvasGroup *parent)
00269 {
00270   GnomeCanvasGroup *borderItem = NULL;
00271 
00272   boardRootItem = GNOME_CANVAS_GROUP(
00273                                  gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
00274                                                      gnome_canvas_group_get_type (),
00275                                                      "x", (double) 0,
00276                                                      "y", (double) 0,
00277                                                      NULL));
00278   borderItem = GNOME_CANVAS_GROUP(
00279                               gnome_canvas_item_new (boardRootItem,
00280                                                   gnome_canvas_group_get_type (),
00281                                                   "x", (double) OFSET_X,
00282                                                   "y", (double) OFSET_Y,
00283                                                   NULL));
00284   draw_grid(borderItem);
00285 
00286   allcars= GNOME_CANVAS_GROUP(
00287                            gnome_canvas_item_new(GNOME_CANVAS_GROUP(borderItem),
00288                                               gnome_canvas_group_get_type(),
00289                                               "x", 11.0,
00290                                               "y", 11.0,
00291                                               NULL));
00292   gtk_object_set_data(GTK_OBJECT(allcars),"whatami",(gpointer)"allcars");
00293 
00294   /* Ready now, let's go */
00295   load_level(gcomprisBoard->level, gcomprisBoard->sublevel);
00296 
00297   return NULL;
00298 }
00299 /* ==================================== */
00300 static void game_won()
00301 {
00302   gcomprisBoard->sublevel++;
00303 
00304   if(gcomprisBoard->sublevel>gcomprisBoard->number_of_sublevel) {
00305     /* Try the next level */
00306     gcomprisBoard->sublevel=1;
00307     gcomprisBoard->level++;
00308     if(gcomprisBoard->level>gcomprisBoard->maxlevel) { // the current board is finished : bail out
00309       gc_bonus_end_display(BOARD_FINISHED_RANDOM);
00310       return;
00311     }
00312     gc_sound_play_ogg ("sounds/bonus.ogg", NULL);
00313   }
00314   traffic_next_level();
00315 }
00316 
00317 /* from canvas.c */
00318 
00319 static void draw_grid(GnomeCanvasGroup *rootBorder)
00320 {
00321   GnomeCanvasGroup *grid_group;
00322   int xlooper, ylooper;
00323 
00324   grid_group = GNOME_CANVAS_GROUP(
00325                               gnome_canvas_item_new(rootBorder,
00326                                                  gnome_canvas_group_get_type(),
00327                                                  "x", 10.0,
00328                                                  "y", 10.0,
00329                                                  NULL));
00330 
00331   gtk_object_set_data(GTK_OBJECT(grid_group),"whatami",(gpointer)"grid_group");
00332 
00333   gnome_canvas_item_lower_to_bottom(GNOME_CANVAS_ITEM(grid_group));
00334 
00335   for (xlooper=0;xlooper<=6;xlooper++)
00336     for (ylooper=0;ylooper<=6;ylooper++)
00337       gtk_object_set_data(GTK_OBJECT(
00338                                  gnome_canvas_item_new(grid_group,
00339                                                     gnome_canvas_rect_get_type(),
00340                                                     "x1", 0.0*xlooper,
00341                                                     "x2", 40.0*xlooper,
00342                                                     "y1", 0.0*ylooper,
00343                                                     "y2", 40.0*ylooper,
00344                                                     "fill_color", NULL,
00345                                                     "outline_color", "white",
00346                                                     "width_units", 2.0,
00347                                                     NULL)),
00348                        "whatami",(gpointer)"grid square");;
00349 }
00350 
00351 
00352 void draw_car(car *thiscar)
00353 {
00354   GnomeCanvasItem *car_group;
00355   GnomeCanvasItem *car_rect;
00356 
00357   gtk_object_set_data(GTK_OBJECT(allcars),"whatami",(gpointer)"allcars");
00358 
00359   car_group=gnome_canvas_item_new(GNOME_CANVAS_GROUP(allcars),
00360                               gnome_canvas_group_get_type(),
00361                               "x",40.0*thiscar->x,
00362                               "y",40.0*thiscar->y,
00363                               NULL);
00364 
00365   car_rect=gnome_canvas_item_new(GNOME_CANVAS_GROUP(car_group),
00366                              gnome_canvas_rect_get_type(),
00367                              "x1",0.0,
00368                              "y1",0.0,
00369                              "x2",(thiscar->orient?40.0*thiscar->size:40.0)-2.25,
00370                              "y2",(thiscar->orient?40.0:40.0*thiscar->size)-2.25,
00371                              "fill_color_rgba", thiscar->color,
00372                              "outline_color", NULL,
00373                              NULL);
00374 
00375   gtk_signal_connect(GTK_OBJECT(car_group),"event",
00376                    GTK_SIGNAL_FUNC(car_cb),(gpointer)thiscar);
00377   gtk_object_set_data(GTK_OBJECT(car_group),"car",(gpointer)thiscar);
00378   gtk_object_set_data(GTK_OBJECT(car_group),"whatami",(gpointer)"car_group");
00379   gtk_object_set_data(GTK_OBJECT(car_rect),"whatami",(gpointer)"car_rect");
00380 }
00381 
00382 void draw_jam(jam *myjam)
00383 {
00384   int whichcar;
00385   for (whichcar=0;whichcar<myjam->num_cars;whichcar++)
00386     draw_car(myjam->cars[whichcar]);
00387 }
00388 
00389 static int car_cb(GnomeCanvasItem *item, GdkEvent *event, car *thiscar)
00390 {
00391   static gboolean moving;
00392   static int button;
00393   static double start_x,start_y;
00394   static double hit=0;
00395   double item_x, item_y;
00396   double world_x, world_y;
00397   double dx,dy;
00398   double small_x, big_x, small_y, big_y;
00399   GdkCursor *cursor;
00400   GnomeCanvasItem *atdest=NULL;
00401   car *othercar=NULL;
00402 
00403   item_x=world_x=event->button.x;
00404   item_y=world_y=event->button.y;
00405   gnome_canvas_item_w2i(item->parent,&item_x,&item_y);
00406 
00407   switch (event->type) {
00408   case GDK_BUTTON_PRESS:
00409     start_x=item_x;
00410     start_y=item_y;
00411     button=event->button.button;
00412 
00413     if (thiscar->orient==CAR_ORIENT_NS)
00414       cursor=gdk_cursor_new(GDK_SB_V_DOUBLE_ARROW);
00415     else
00416       cursor=gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW);
00417     gc_canvas_item_grab(item,
00418                         GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
00419                         cursor,
00420                         event->button.time);
00421     gdk_cursor_destroy(cursor);
00422 
00423     moving=TRUE;
00424     break;
00425   case GDK_MOTION_NOTIFY:
00426     if (moving)
00427       switch (thiscar->orient) {
00428       case CAR_ORIENT_NS:
00429        small_x=0;
00430        big_x=40-1;
00431        small_y=0;
00432        big_y=40*thiscar->size-1;
00433 
00434        gnome_canvas_item_i2w(item,&small_x,&small_y);
00435        gnome_canvas_item_i2w(item,&big_x,&big_y);
00436 
00437        dy=CLAMP(item_y-start_y,-39,39);
00438        dx=CLAMP(item_x-start_x,-39,39);
00439 
00440        if (small_y+dy<11+OFSET_Y) {
00441          dy=11-small_y+OFSET_Y;
00442        } else if (big_y+dy>250+OFSET_Y) {
00443          dy=250-big_y+OFSET_Y;
00444        }
00445 
00446        if ((hit<0)!=(dy<0)) { hit=0; }
00447 
00448        if (hit==0) {
00449          if (dy>0) {
00450            do {
00451              atdest=gnome_canvas_get_item_at(gcomprisBoard->canvas,
00452                                          small_x+20,
00453                                          big_y+dy);
00454              if (atdest)
00455               othercar=(car*)gtk_object_get_data(GTK_OBJECT(atdest->parent),"car");
00456              if (othercar) {
00457               hit=1;
00458               dy--;
00459              }
00460            } while (othercar);
00461          } else if (dy<0) {
00462            do {
00463              atdest=gnome_canvas_get_item_at(gcomprisBoard->canvas,
00464                                          small_x+20,small_y+dy-1);
00465              if (atdest)
00466               othercar=(car*)gtk_object_get_data(GTK_OBJECT(atdest->parent),"car");
00467              if (othercar) {
00468               hit=-1;
00469               dy++;
00470              }
00471            } while (othercar);
00472          }
00473        } else { dy=0; }
00474 
00475        start_x+=dx;
00476        start_y+=dy;
00477 
00478        gnome_canvas_item_move(item,0,dy);
00479        gnome_canvas_item_request_update(item);
00480 
00481        break;
00482       case CAR_ORIENT_EW:
00483        small_x=0;
00484        big_x=40*thiscar->size-1;
00485        small_y=0;
00486        big_y=40-1;
00487 
00488        gnome_canvas_item_i2w(item,&small_x,&small_y);
00489        gnome_canvas_item_i2w(item,&big_x,&big_y);
00490 
00491        dy=CLAMP(item_y-start_y,-39,39);
00492        dx=CLAMP(item_x-start_x,-39,39);
00493 
00494        if (thiscar->goal && big_x==250+OFSET_X) {
00495          gc_canvas_item_ungrab(item,event->button.time);
00496          gnome_canvas_item_hide(item);
00497          moving=FALSE;
00498 
00499          gamewon = TRUE;
00500          gc_bonus_display(gamewon, BONUS_SMILEY);
00501 
00502        }
00503 
00504        if (small_x+dx<11+OFSET_X) {
00505          dx=11-small_x+OFSET_X;
00506        } else if (big_x+dx>250+OFSET_X) {
00507          dx=250-big_x+OFSET_X;
00508        }
00509 
00510        if ((hit<0)!=(dx<0)) { hit=0;}
00511 
00512        if (hit==0) {
00513          if (dx>0) {
00514            do {
00515              atdest=gnome_canvas_get_item_at(gcomprisBoard->canvas,
00516                                          big_x+dx,small_y+20);
00517              if (atdest)
00518               othercar=(car*)gtk_object_get_data(GTK_OBJECT(atdest->parent),"car");
00519              if (othercar) {
00520               hit=1;
00521               dx--;
00522              }
00523            } while (othercar);
00524          } else if (dx<0) {
00525            do {
00526              atdest=gnome_canvas_get_item_at(gcomprisBoard->canvas,
00527                                          small_x+dx-1,small_y+20);
00528              if (atdest)
00529               othercar=(car*)gtk_object_get_data(GTK_OBJECT(atdest->parent),"car");
00530              if (othercar) {
00531               hit=-1;
00532               dx++;
00533              }
00534            } while (othercar);
00535          }
00536        } else { dx=0; }
00537 
00538        start_x+=dx;
00539        start_y+=dy;
00540 
00541        gnome_canvas_item_move(item,dx,0);
00542        gnome_canvas_item_request_update(item);
00543 
00544        break;
00545       default:
00546        break;
00547       }
00548   case GDK_BUTTON_RELEASE:
00549     if (moving && (event->button.button==button))
00550       {
00551        double even_vals_x[]={11+OFSET_X,51+OFSET_X,91+OFSET_X,131+
00552                            OFSET_X,171+OFSET_X,211+OFSET_X,HUGE_VAL};
00553        double even_vals_y[]={11+OFSET_Y,51+OFSET_Y,91+OFSET_Y,131+
00554                            OFSET_Y,171+OFSET_Y,211+OFSET_Y,HUGE_VAL};
00555        double *ptr;
00556        double x=0,y=0;
00557 
00558        gnome_canvas_item_i2w(item,&x,&y);
00559 
00560        for (ptr=even_vals_x;*ptr<x;ptr++);
00561        if (*ptr-x>20)
00562          dx=*(ptr-1)-x;
00563        else
00564          dx=*ptr-x;
00565 
00566        for (ptr=even_vals_y;*ptr<y;ptr++);
00567        if (*ptr-y>20)
00568          dy=*(ptr-1)-y;
00569        else
00570          dy=*ptr-y;
00571 
00572        gnome_canvas_item_move(item,dx,dy);
00573        gc_canvas_item_ungrab(item,event->button.time);
00574        hit=0;
00575        moving=FALSE;
00576       }
00577     break;
00578   default:
00579     break;
00580   }
00581   return TRUE;
00582 }
00583 
00584 /* From jam.c */
00585 
00586 gboolean load_level(guint level, guint sublevel)
00587 {
00588   char *car_strv=NULL;
00589 
00590   current_card.level = level;
00591   current_card.card  = sublevel;
00592 
00593   car_strv = DataList[(level-1) * gcomprisBoard->number_of_sublevel + (sublevel-1)];
00594 
00595   current_card.num_cars = cars_from_strv(car_strv);
00596 
00597   if(current_card.num_cars == -1)
00598     g_error("In loading dataset for traffic activity");
00599 
00600   draw_jam(&current_card);
00601 
00602   return TRUE;
00603 }
00604 
00605 /* Returns the number of cars
00606  * I took the formatting from
00607  *  http://www.javascript-games.org/puzzle/rushhour/
00608  */
00609 gint cars_from_strv(char *strv)
00610 {
00611   car *ccar;
00612   char x,y,id;
00613   int number_of_cars = 0;
00614   gboolean more_car = TRUE;
00615 
00616   while (more_car) {
00617 
00618     current_card.cars[number_of_cars] = (car *)g_new(car, 1);
00619     ccar = current_card.cars[number_of_cars];
00620 
00621     /* By default, not a goal car */
00622     ccar->goal   = 0;
00623 
00624     number_of_cars++;
00625 
00626     if (sscanf(strv,"%c%c%c",
00627               &id,&x,&y)!=3) {
00628       return -1;
00629     }
00630 
00631     /* Point to the next car */
00632     strv += 3;
00633 
00634     if(strv[0] != ',')
00635       more_car = FALSE;
00636 
00637     strv += 1;
00638 
00639     if (id == 'O' || id == 'P' || id == 'Q' || id == 'R') ccar->size = 3;
00640     else ccar->size = 2;
00641 
00642     ccar->orient = 1;
00643     ccar->x = 0;
00644     ccar->y = y-'1';
00645 
00646     if (x == 'A') ccar->x = 0;
00647     else if (x == 'B') ccar->x = 1;
00648     else if (x == 'C') ccar->x = 2;
00649     else if (x == 'D') ccar->x = 3;
00650     else if (x == 'E') ccar->x = 4;
00651     else if (x == 'F') ccar->x = 5;
00652     else {
00653       ccar->y = x-'1';
00654       ccar->orient = 0;
00655 
00656       if (y == 'A') ccar->x = 0;
00657       else if (y == 'B') ccar->x = 1;
00658       else if (y == 'C') ccar->x = 2;
00659       else if (y == 'D') ccar->x = 3;
00660       else if (y == 'E') ccar->x = 4;
00661       else if (y == 'F') ccar->x = 5;
00662     }
00663 
00664     if (id == 'X')
00665       {
00666        ccar->color  = 0xFF0000FF;
00667        ccar->goal   = 1;
00668       }
00669     else if (id == 'A') ccar->color = 0x80FF80FF;
00670     else if (id == 'B') ccar->color = 0xC0C000FF;
00671     else if (id == 'C') ccar->color = 0x8080FFFF;
00672     else if (id == 'D') ccar->color = 0xFF80FFFF;
00673     else if (id == 'E') ccar->color = 0xC00000FF;
00674     else if (id == 'F') ccar->color = 0x008000FF;
00675     else if (id == 'G') ccar->color = 0xC0C0C0FF;
00676     else if (id == 'H') ccar->color = 0x6000efFF;
00677     else if (id == 'I') ccar->color = 0xFFFF00FF;
00678     else if (id == 'J') ccar->color = 0xFFA801FF;
00679     else if (id == 'K') ccar->color = 0x00FF00FF;
00680     else if (id == 'O') ccar->color = 0xFFFF00FF;
00681     else if (id == 'P') ccar->color = 0xFF80FFFF;
00682     else if (id == 'Q') ccar->color = 0x0000FFFF;
00683     else if (id == 'R') ccar->color = 0x00FFFFFF;
00684 
00685   }
00686   return number_of_cars;
00687 }
00688