ArenaBase.cc

Go to the documentation of this file.
00001 /*
00002 RealTimeBattle, a robot programming game for Unix
00003 Copyright (C) 1998-2000  Erik Ouchterlony and Ragnar Ouchterlony
00004 
00005 This program is free software; you can redistribute it and/or modify
00006 it under the terms of the GNU General Public License as published by
00007 the Free Software Foundation; either version 2 of the License, or
00008 (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software Foundation,
00017 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 */
00019 
00020 
00021 
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include <math.h>
00028 #include <signal.h>
00029 #include <unistd.h>
00030 #include <stdlib.h>
00031 #include <iostream>
00032 #include <iomanip>
00033 #include <stdarg.h>
00034 
00035 #if HAVE_DIRENT_H
00036 # include <dirent.h>
00037 # define NAMLEN(dirent) strlen((dirent)->d_name)
00038 #else
00039 # define dirent direct
00040 # define NAMLEN(dirent) (dirent)->d_namlen
00041 # if HAVE_SYS_NDIR_H
00042 #  include <sys/ndir.h>
00043 # endif
00044 # if HAVE_SYS_DIR_H
00045 #  include <sys/dir.h>
00046 # endif
00047 # if HAVE_NDIR_H
00048 #  include <ndir.h>
00049 # endif
00050 #endif
00051 
00052 //#include "Gui.h"
00053 #include "ArenaBase.h"
00054 #include "ArenaController.h"
00055 //#include "MovingObject.h"
00056 //#include "Shape.h"
00057 #include "IntlDefs.h"
00058 #include "Extras.h"
00059 #include "Various.h"
00060 #include "String.h"
00061 #include "Shot.h"
00062 #include "Options.h"
00063 #include "Wall.h"
00064 #include "Robot.h"
00065 
00066 #ifndef NO_GRAPHICS
00067 # include "ControlWindow.h"
00068 # include "MessageWindow.h"
00069 extern class ControlWindow* controlwindow_p;
00070 #endif 
00071 
00072 ArenaBase::ArenaBase()
00073 {
00074   state = NOT_STARTED;
00075   game_mode = NORMAL_MODE;
00076 
00077   sequence_nr = 0;
00078   sequences_in_tournament = 0;
00079   game_nr = 0;
00080   games_per_sequence = 0;
00081 
00082   halt_next = false;
00083   pause_after_next_game = false;
00084 
00085   reset_timer();
00086   
00087   object_lists[ROBOT].set_deletion_responsibility(false);
00088   all_robots_in_sequence.set_deletion_responsibility(false);
00089 
00090   debug_level = 0;
00091 }
00092 
00093 ArenaBase::~ArenaBase()
00094 {
00095   //  if( filep ) delete filep;
00096   state = EXITING;
00097   sleep(1);
00098 
00099   delete_lists(true, true, true, true);
00100 }
00101 
00102 void
00103 ArenaBase::set_state( const state_t st )
00104 {
00105   state = st;
00106 
00107 #ifndef NO_GRAPHICS
00108   if( !no_graphics )
00109     {
00110       String infotext;
00111       switch( state )
00112         {
00113         case NO_STATE:
00114         case NOT_STARTED:
00115           infotext = "RealTimeBattle";
00116           break;
00117         case STARTING_ROBOTS:
00118           infotext = "RTB  " + (String)_("*Starting robots*");
00119           break;
00120         case SHUTTING_DOWN_ROBOTS:
00121           infotext = "RTB  " + (String)_("*Shutting down robots*");
00122           break;
00123         case BEFORE_GAME_START:
00124         case GAME_IN_PROGRESS:
00125           infotext = "RealTimeBattle  " + (String)_("*Running*");
00126           if( pause_after_next_game )
00127             infotext = "RTB  " + (String)_("*Pausing after game*");
00128           break;
00129         case PAUSING_BETWEEN_GAMES:
00130         case PAUSED:
00131           infotext = "RealTimeBattle  " + (String)_("*Paused*");
00132           break;
00133         case EXITING:
00134           infotext = "RealTimeBattle  " + (String)_("*Exiting*");
00135           break;
00136         case FINISHED:
00137           infotext = "RealTimeBattle  " + (String)_("*Finished*");
00138           break;
00139           
00140         default:
00141           Error(true, "Unknown state", "ArenaBase::set_state");
00142         }
00143       
00144       controlwindow_p->set_window_title( infotext );
00145     }
00146 #endif 
00147 }
00148 
00149 void 
00150 ArenaBase::interrupt_tournament()
00151 {
00152   if( state == GAME_IN_PROGRESS || state == PAUSED ||
00153       state == PAUSING_BETWEEN_GAMES )
00154     {
00155       the_arena_controller.auto_start_and_end = false;
00156 #ifndef NO_GRAPHICS
00157       if( !no_graphics )
00158         {
00159           controlwindow_p->remove_replay_widgets();
00160           the_gui.close_scorewindow();
00161           the_gui.close_arenawindow();
00162           the_gui.close_messagewindow();
00163         }
00164 #endif
00165 
00166       delete_lists(true, true, false, true);
00167       
00168       set_state( FINISHED );
00169     }
00170 }
00171 
00172 // This function takes the statistics and saves into a selected file
00173 void
00174 ArenaBase::save_statistics_to_file(String filename)
00175 {
00176   
00177   
00178   ofstream file(filename.chars());
00179 
00180   stat_t* statp;
00181   Robot* robotp;
00182 
00183   ListIterator<Robot> li;
00184   ListIterator<stat_t> stat_li;
00185   for(all_robots_in_tournament.first(li); li.ok() ; li++ )
00186     {
00187       robotp = li();
00188       file << robotp->get_robot_name() << ": " << endl;
00189       for(robotp->get_statistics()->first(stat_li); stat_li.ok(); stat_li++)
00190         {
00191           statp = stat_li();
00192           file << "Seq: " << statp->sequence_nr 
00193                << "  Game: " << statp->game_nr 
00194                << "  Pos: " << statp->position
00195                << "  Points: " << statp->points 
00196                << "  Time Survived: " << statp->time_survived
00197                << "  Total Points: " << statp->total_points << endl;
00198         }
00199     }
00200     
00201     
00202 }
00203 
00204 void
00205 ArenaBase::print_message( const String& messager,
00206                           const String& text )
00207 {
00208   if( use_message_file )
00209     message_file << messager << ": " << text << endl;
00210 #ifndef NO_GRAPHICS
00211   else if( !no_graphics && the_gui.is_messagewindow_up() )
00212     the_gui.get_messagewindow_p()->add_message( messager, text );
00213 #endif
00214 }
00215 
00216 void
00217 ArenaBase::parse_arena_line(ifstream& file, double& scale, int& succession, double& angle_factor)
00218 {
00219   char text[20];
00220   double radius, radius2, bounce_c, hardn, thickness;
00221   int vertices;
00222 
00223   Vector2D vec1, vec2, vec0, center;
00224   WallLine* wall_linep;
00225   WallCircle* wall_circlep;
00226   WallInnerCircle* wall_inner_circlep;
00227   WallArc* wall_arcp;
00228 
00229 
00230   file >> ws;
00231   file.get(text, 20, ' ');
00232   if( strcmp(text, "scale" ) == 0 )
00233     {
00234       if( succession != 1 ) Error(true, "Error in arenafile: 'scale' not first", 
00235                                   "ArenaBase::parse_arena_line");
00236       succession = 2;
00237       double scl;
00238       file >> scl;
00239       scale *= scl;
00240     }
00241   else if( strcmp(text, "angle_unit" ) == 0 )
00242     {
00243       char unit[20];
00244       file >> ws;
00245       file.get(unit, 20, '\n');
00246       if( strcmp(unit, "radians" ) == 0)
00247         angle_factor = 1.0;
00248       else if( strcmp(unit, "degrees" ) == 0 )
00249         angle_factor = M_PI / 180.0;
00250       else
00251         Error(true, "Error in arenafile: Unknown angle unit: " + String(unit), 
00252               "ArenaBase::parse_arena_line");
00253     }
00254   else if( strcmp(text, "boundary" ) == 0 )
00255     {
00256       if( succession > 2 ) 
00257         Error(true, "Error in arenafile: 'boundary' after wallpieces or duplicate", 
00258               "ArenaBase::parse_arena_line");
00259       succession = 3;
00260       double b1, b2;
00261       file >> b1;
00262       file >> b2;
00263       boundary[0] = Vector2D(scale*b1, scale*b2);
00264       file >> b1;
00265       file >> b2;
00266       boundary[1] = Vector2D(scale*b1, scale*b2);
00267       if( boundary[1][0] - boundary[0][0] <= 0 || 
00268           boundary[1][1] - boundary[0][1] <= 0 ) 
00269         Error(true, "Error in arenafile: 'boundary' negative", 
00270               "ArenaBase::parse_arena_line");
00271     }
00272   else if( strcmp(text, "exclusion_point" ) == 0 )
00273     {
00274       if( succession < 3 ) 
00275         Error(true, "Error in arenafile: 'boundary' after wallpieces or duplicate", 
00276               "ArenaBase::parse_arena_line");
00277       file >> vec1;
00278       exclusion_points.insert_last(new Vector2D(scale*vec1));
00279     }
00280   else if( strcmp(text, "inner_circle" ) == 0 )
00281     {
00282       if( succession < 3 ) 
00283         Error(true, "Error in arenafile: 'inner_circle' before boundary", 
00284               "ArenaBase::parse_arena_line");
00285       succession = 4;
00286       file >> bounce_c;
00287       file >> hardn;
00288       file >> vec1;
00289       file >> radius;
00290       
00291       wall_inner_circlep = new WallInnerCircle(scale*vec1, scale*radius, bounce_c, hardn);
00292       object_lists[WALL].insert_first( wall_inner_circlep );
00293     }
00294   else if( strcmp(text, "circle" ) == 0 )
00295     {
00296       if( succession < 3 ) 
00297         Error(true, "Error in arenafile: 'circle' before 'boundary'", 
00298               "ArenaBase::parse_arena_line");
00299       succession = 4;
00300       file >> bounce_c;
00301       file >> hardn;
00302       file >> vec1;
00303       file >> radius;
00304       wall_circlep = new WallCircle(scale*vec1, scale*radius, bounce_c, hardn);
00305       object_lists[WALL].insert_last(wall_circlep);
00306     }
00307   else if( strcmp(text, "arc" ) == 0 )
00308     {
00309       if( succession < 3 ) 
00310         Error(true, "Error in arenafile: 'arc' before 'boundary'", 
00311               "ArenaBase::parse_arena_line");
00312       succession = 4;
00313       double angle1, angle2;
00314       file >> bounce_c;
00315       file >> hardn;
00316       file >> center;
00317       file >> radius;
00318       file >> radius2;
00319       file >> angle1;
00320       file >> angle2;
00321       
00322       wall_arcp = new WallArc(scale*center, scale*radius, scale*radius2, 
00323                               angle1 * angle_factor, angle2 * angle_factor,
00324                               bounce_c, hardn);
00325       object_lists[WALL].insert_last(wall_arcp);
00326     }
00327   else if( strcmp(text, "line" ) == 0 )
00328     {
00329       if( succession < 3 ) Error(true, "Error in arenafile: 'line' before 'boundary'",
00330                                  "ArenaBase::parse_arena_line");
00331       succession = 4;
00332       file >> bounce_c;
00333       file >> hardn;
00334       file >> thickness; 
00335       thickness *= 0.5;
00336       file >> vec1;      // start_point
00337       file >> vec2;      // end_point
00338 
00339 
00340       if( length(vec2-vec1) == 0.0 ) 
00341         Error(true, "Error in arenafile: Zero length line", 
00342               "ArenaBase::parse_arena_line");
00343 
00344       wall_linep = new WallLine(scale*vec1, unit(vec2-vec1), scale*length(vec2-vec1), 
00345                                 scale*thickness, bounce_c , hardn);      
00346       object_lists[WALL].insert_last( wall_linep );
00347     }
00348   else if( strcmp(text, "polygon" ) == 0 )
00349     {
00350       if( succession < 3 ) 
00351         Error(true, "Error in arenafile: 'polygon' before 'boundary'", 
00352               "ArenaBase::parse_arena_line");
00353       succession = 4;
00354       file >> bounce_c;
00355       file >> hardn;
00356       file >> thickness;
00357       thickness *= 0.5;
00358       file >> vertices;   // number of vertices
00359       file >> vec1;      // first point
00360       wall_circlep = new WallCircle(scale*vec1, scale*thickness, bounce_c, hardn);
00361       object_lists[WALL].insert_last( wall_circlep );
00362 
00363       for(int i=1; i<vertices; i++)
00364         {
00365           vec2 = vec1;
00366           file >> vec1;      // next point
00367 
00368           if( length(vec2-vec1) == 0.0 ) 
00369             Error(true, "Error in arenafile: Zero length line in polygon", 
00370                   "ArenaBase::parse_arena_line");
00371 
00372           wall_linep = new WallLine(scale*vec2, unit(vec1-vec2), 
00373                                     scale*length(vec1-vec2), 
00374                                     scale*thickness, bounce_c , hardn);      
00375           object_lists[WALL].insert_last( wall_linep );
00376           wall_circlep = new WallCircle(scale*vec1, scale*thickness, bounce_c, hardn);
00377           object_lists[WALL].insert_last( wall_circlep );
00378         }
00379     }
00380   else if( strcmp(text, "closed_polygon" ) == 0 )
00381     {
00382       if( succession < 3 ) 
00383         Error(true, "Error in arenafile: 'closed_polygon' before 'boundary'", 
00384               "ArenaBase::parse_arena_line");
00385       succession = 4;
00386       file >> bounce_c;
00387       file >> hardn;
00388       file >> thickness;
00389       thickness *= 0.5;
00390       file >> vertices;   // number of vertices
00391       file >> vec1;      // first point
00392       wall_circlep = new WallCircle(scale*vec1, scale*thickness, bounce_c, hardn);
00393       object_lists[WALL].insert_last( wall_circlep );
00394       vec0 = vec1;
00395 
00396       for(int i=1; i<vertices; i++)
00397         {
00398           vec2 = vec1;
00399           file >> vec1;      // next point
00400 
00401           if( length(vec2-vec1) == 0.0 )
00402             Error(true, "Error in arenafile: Line in closed_polygon of zero length", 
00403                   "ArenaBase::parse_arena_line");
00404           
00405           wall_linep = new WallLine(scale*vec2, unit(vec1-vec2), 
00406                                     scale*length(vec1-vec2), 
00407                                     scale*thickness, bounce_c , hardn);      
00408           object_lists[WALL].insert_last( wall_linep );
00409           wall_circlep = new WallCircle(scale*vec1, scale*thickness, bounce_c, hardn);
00410           object_lists[WALL].insert_last( wall_circlep );
00411         }
00412 
00413       if( length(vec0-vec1) == 0.0 ) 
00414         Error(true, "Error in arenafile: Last line in closed_polygon of zero length", 
00415               "ArenaBase::parse_arena_line");
00416 
00417       wall_linep = new WallLine(scale*vec1, unit(vec0-vec1), scale*length(vec0-vec1), 
00418                                 scale*thickness, bounce_c , hardn);      
00419       object_lists[WALL].insert_last( wall_linep );
00420     }
00421 
00422   else if( strcmp(text, "poly_curve" ) == 0 )
00423     {
00424       if( succession < 3 ) 
00425         Error(true, "Error in arenafile: 'closed_polygon' before 'boundary'", 
00426               "ArenaBase::parse_arena_line");
00427       succession = 4;
00428       file >> bounce_c;
00429       file >> hardn;
00430       file >> thickness;
00431       thickness *= 0.5;
00432 
00433       Vector2D current_pos, direction;
00434       file >> current_pos;      // first point
00435       wall_circlep = new WallCircle(scale*current_pos, scale*thickness, bounce_c, hardn);
00436       object_lists[WALL].insert_last( wall_circlep );
00437 
00438       file >> direction;      // start direction      
00439       
00440       direction.normalize();
00441 
00442       if( lengthsqr(direction) < 0.01 ) 
00443         Error(true, "Error in arenafile: directions must not be zero", 
00444               "ArenaBase::parse_arena_line");
00445 
00446       vec0 = current_pos;
00447 
00448       char c;
00449       double len, angle, start_angle, end_angle, tmp;
00450       bool finish = false;
00451       do
00452         {
00453           file >> c;
00454           
00455           switch( c )
00456             {
00457             case 'L':  // line
00458               file >> len;
00459               if( len <= 0.0 )
00460                 Error(true, "Error in arenafile: Line in poly_curve must be positive", 
00461                       "ArenaBase::parse_arena_line");
00462                 
00463               wall_linep = new WallLine(scale*current_pos, direction, 
00464                                         scale*len, 
00465                                         scale*thickness, bounce_c , hardn);      
00466               object_lists[WALL].insert_last( wall_linep );
00467 
00468               current_pos += len * direction;
00469               wall_circlep = new WallCircle(scale*current_pos, scale*thickness, 
00470                                             bounce_c, hardn);
00471               object_lists[WALL].insert_last( wall_circlep );
00472               
00473               break;
00474             case 'A':  // Arc
00475               file >> angle;
00476               file >> radius;
00477 
00478               angle *= angle_factor;
00479               center = current_pos - rotate90( direction ) * radius * sgn( angle );
00480               start_angle = vec2angle( current_pos - center );
00481               current_pos = center + radius * angle2vec( start_angle - angle );
00482               end_angle = vec2angle( current_pos - center );
00483 
00484               if( angle > 0.0 )
00485                 { tmp = start_angle; start_angle = end_angle; end_angle = tmp; }
00486 
00487               wall_arcp = new WallArc(scale*center, scale*(radius - thickness), 
00488                                       scale*(radius + thickness), 
00489                                       start_angle, end_angle,
00490                                       bounce_c, hardn);
00491 
00492               object_lists[WALL].insert_last(wall_arcp);              
00493 
00494 
00495               direction = rotate(direction, -angle);
00496 
00497               wall_circlep = new WallCircle(scale*current_pos, scale*thickness, 
00498                                             bounce_c, hardn);
00499               object_lists[WALL].insert_last( wall_circlep );
00500               break;
00501 
00502             case 'T':  // Turn
00503               file >> angle;              
00504               direction = rotate( direction, -angle*M_PI/180.0 );
00505 
00506               break;
00507               
00508             case 'C':   // connect to start point and quit
00509               if( length(vec0 - current_pos ) == 0.0 ) 
00510                 Error(true, "Error in arenafile: Last line in poly_curve of zero length", 
00511                       "ArenaBase::parse_arena_line");
00512               
00513               wall_linep = new WallLine(scale*current_pos, unit(vec0-current_pos), 
00514                                         scale*length(vec0-current_pos), 
00515                                         scale*thickness, bounce_c , hardn);      
00516               object_lists[WALL].insert_last( wall_linep );              
00517 
00518               finish = true;
00519               break;
00520             case 'Q':   // quit
00521               finish = true;
00522               break;
00523               
00524             default:
00525               Error(true, "Incorrect arenafile, unknown command in poly_curve: " 
00526                     + (String)c, "ArenaBase::parse_arena_line");
00527               break;
00528             }
00529         }
00530       while( !finish );
00531     }
00532 
00533   else if( text[0] != '\0' )
00534     Error(true, "Incorrect arenafile, unknown keyword: " + (String)text, 
00535           "ArenaBase::parse_arena_line");
00536 
00537 }
00538 
00539 
00540 
00541 double
00542 ArenaBase::get_shortest_distance(const Vector2D& pos, const Vector2D& dir, 
00543                                   const double size, object_type& closest_shape, 
00544                                   Shape*& colliding_object, const Robot* the_robot)
00545 {
00546   double dist = infinity;
00547   double d;
00548   closest_shape = NOOBJECT;
00549 
00550   ListIterator<Shape> li;
00551 
00552   for( int obj_type = ROBOT; obj_type < LAST_OBJECT_TYPE; obj_type++ )
00553     {
00554       for( object_lists[obj_type].first(li); li.ok(); li++)
00555         {
00556           if( obj_type != ROBOT || (Robot*)(li()) != the_robot )
00557             {
00558               d = li()->get_distance(pos, dir, size);
00559               if( d < dist)
00560                 {
00561                   closest_shape = (object_type)obj_type;
00562                   colliding_object = li();
00563                   dist = d;
00564                 }
00565             }
00566         }
00567     }
00568 
00569   return dist;
00570 }
00571 
00572 bool
00573 ArenaBase::space_available(const Vector2D& pos, const double margin)
00574 {
00575   ListIterator<Shape> li;
00576 
00577   for( int obj_type = ROBOT; obj_type < LAST_OBJECT_TYPE; obj_type++ )
00578     {
00579       for( object_lists[obj_type].first(li); li.ok(); li++)
00580         if( li()->within_distance(pos, margin) ) return false;
00581     }
00582 
00583   // Check if it is possible to see any exclusion_points
00584   
00585   Vector2D vec;
00586   double dist;
00587   object_type obj_t;
00588   Shape* shapep;
00589 
00590   ListIterator<Vector2D> li_ex;
00591 
00592   for( exclusion_points.first(li_ex); li_ex.ok(); li_ex++)
00593     {
00594       vec = *(li_ex());
00595       dist = length(vec - pos);
00596       if( dist <= margin || 
00597           dist <= get_shortest_distance(pos, unit(vec - pos), 0.0, 
00598                                         obj_t, shapep, (Robot*)NULL) )
00599         return false;
00600     }
00601 
00602   return true;
00603 }
00604 
00605 
00606 double 
00607 ArenaBase::get_shooting_penalty() 
00608 { 
00609   return min( the_opts.get_d(OPTION_SHOOTING_PENALTY), 0.5 / (double)robots_left ); 
00610 }
00611 
00612 
00613 void
00614 ArenaBase::update_timer(const double factor)
00615 {
00616   double last_timer = current_timer;
00617 
00618   current_timer = timer.get();
00619   double timescale = 1.0;
00620   if( state == GAME_IN_PROGRESS ) timescale = the_opts.get_d(OPTION_TIMESCALE);
00621   timestep = min( (current_timer - last_timer) * timescale, 
00622                   the_opts.get_d(OPTION_MAX_TIMESTEP) );
00623   total_time += timestep*factor;
00624 
00625   total_time = max(total_time, 0.0);
00626 }
00627 
00628 void
00629 ArenaBase::reset_timer()
00630 {
00631   total_time = 0.0;
00632   current_timer = 0.0;
00633   timer.reset();
00634   update_timer();
00635 }
00636 
00637 
00638 void
00639 ArenaBase::move_shots(const double time_period)
00640 {
00641   Shot* shotp;
00642 
00643   ListIterator<Shape> li;
00644 
00645   for( object_lists[SHOT].first(li); li.ok(); li++)
00646     {
00647       shotp = (Shot*)li();
00648 
00649       if( shotp->is_alive() ) shotp->move(time_period);
00650 
00651       if( !shotp->is_alive() ) object_lists[SHOT].remove(li);
00652     }
00653 }
00654 
00655 void
00656 ArenaBase::move_shots_no_check(const double time_period)
00657 {
00658   ListIterator<Shape> li;
00659 
00660   for( object_lists[SHOT].first(li); li.ok(); li++)
00661     {
00662       ((Shot*)li())->move_no_check(time_period);
00663     }
00664 }
00665 
00666 void 
00667 ArenaBase::set_game_mode( const enum game_mode_t gm )
00668 {
00669   game_mode = gm; 
00670   if( game_mode == DEBUG_MODE )
00671     {
00672       if( debug_level == 0 )
00673         set_debug_level( the_arena_controller.debug_level );
00674     }
00675   else
00676     {
00677       debug_level = 0;
00678     }
00679 }
00680 
00681 int
00682 ArenaBase::set_debug_level( const int new_level)
00683 {
00684   if( new_level > max_debug_level || new_level < 0 || new_level == debug_level )
00685     return debug_level;
00686   
00687   debug_level = new_level;
00688 
00689   return debug_level;
00690 }
00691 
00692 void
00693 ArenaBase::pause_game_toggle()
00694 {
00695   if( game_mode != COMPETITION_MODE )
00696     {
00697       if( state == GAME_IN_PROGRESS ) 
00698         set_state( PAUSED );
00699       else if( state == PAUSED ) 
00700         set_state( GAME_IN_PROGRESS );
00701 
00702       halt_next = false; 
00703     }
00704   else
00705     {
00706       pause_after_next_game = !pause_after_next_game;
00707       set_state( state ); // to change control window title
00708     }
00709 }
00710 
00711 void
00712 ArenaBase::step_paused_game()
00713 {
00714   if( game_mode == DEBUG_MODE && state == PAUSED )
00715     {
00716       halt_next = true; 
00717       set_state( GAME_IN_PROGRESS );
00718     }
00719 }
00720 
00721 void
00722 ArenaBase::delete_lists(const bool kill_robots, const bool del_seq_list, 
00723                         const bool del_tourn_list, const bool del_arena_filename_list, 
00724                         const bool del_robot_obj_list)
00725 {
00726   // clear the lists;
00727 
00728   for( int obj_type = ROBOT; obj_type < LAST_OBJECT_TYPE; obj_type++ )
00729     if( obj_type != ROBOT || del_robot_obj_list )
00730       object_lists[obj_type].delete_list();
00731 
00732   exclusion_points.delete_list();
00733 
00734   if( del_seq_list )
00735     {
00736       if( kill_robots )
00737         {
00738           ListIterator<Robot> li;
00739           for( all_robots_in_sequence.first(li); li.ok(); li++)
00740             li()->kill_process_forcefully();
00741         }
00742       all_robots_in_sequence.delete_list();
00743     }
00744 
00745   if( del_tourn_list )  all_robots_in_tournament.delete_list();
00746   if( del_arena_filename_list ) arena_filenames.delete_list();
00747 }
00748 
00749 bool
00750 ArenaBase::find_object_by_id( const List<Shape>& obj_list, 
00751                               ListIterator<Shape>& li,
00752                               const int obj_id )
00753 {
00754   for( obj_list.first(li); li.ok(); li++)
00755     {
00756       if( li()->get_id() == obj_id ) 
00757         return true;
00758     }
00759   return false;
00760 }
00761 
00762 bool
00763 ArenaBase::find_object_by_id( const List<Robot>& obj_list, 
00764                               ListIterator<Robot>& li,
00765                               const int obj_id )
00766 {
00767   for( obj_list.first(li); li.ok(); li++)
00768     {
00769       if( li()->get_id() == obj_id ) 
00770         return true;
00771     }
00772   return false;
00773 }

Generated on Fri Oct 15 15:47:35 2004 for Real Time Battle by  doxygen 1.3.9.1