ArenaRealTime Class Reference

#include <ArenaRealTime.h>

Inheritance diagram for ArenaRealTime:

Inheritance graph
[legend]
Collaboration diagram for ArenaRealTime:

Collaboration graph
[legend]

Public Member Functions

 ArenaRealTime ()
virtual ~ArenaRealTime ()
void clear ()
bool timeout_function ()
void start_tournament (const List< start_tournament_info_t > &robotfilename_list, const List< start_tournament_info_t > &arenafilename_list, const int robots_p_game, const int games_p_sequence, const int n_o_sequences)
void end_game ()
void broadcast (enum message_to_robot_type...)
void parse_arena_file (String &filename)
void set_filenames (String &log_fname, const String &statistics_fname, const String &tournament_fname, String &message_fname, const String &option_fname)
void print_to_logfile (const char first_letter...)
bool get_use_message_file ()
Vector2D get_random_position ()
List< Stringget_arena_filenames ()
int get_current_arena_nr ()
int set_debug_level (const int new_level)
int get_max_debug_level ()
void quit_ordered ()
long int find_free_colour (const long int home_colour, const long int away_colour, const class Robot *, const bool random_colours=false)

Static Public Member Functions

void start_tournament_from_tournament_file (const List< start_tournament_info_t > &robotfilename_list, const List< start_tournament_info_t > &arenafilename_list, const int robots_p_game, const int games_p_sequence, const int n_o_sequences, ArenaRealTime *ar_p)

Private Member Functions

void check_initialization ()
void update ()
void update_robots ()
void read_robot_messages ()
void check_robots ()
void add_cookie ()
void add_mine ()
bool is_colour_allowed (const long int col, const double min_dist, const class Robot *)
double colour_dist (const long int col1, const long int col2)
void start_game ()
void start_sequence ()
void end_sequence ()
void start_sequence_follow_up ()
void end_sequence_follow_up ()
void end_tournament ()

Private Attributes

String tournament_file_name
ofstream LOG_FILE
bool use_log_file
int update_count_for_logging
int ** robots_in_sequence
double next_check_time
int number_of_arenas
int current_arena_nr

Constructor & Destructor Documentation

ArenaRealTime::ArenaRealTime  ) 
 

Definition at line 61 of file ArenaRealTime.cc.

References ArenaController::game_mode, ArenaController::log_filename, ArenaController::message_filename, ArenaController::option_filename, robots_in_sequence, set_filenames(), ArenaBase::set_game_mode(), ArenaController::statistics_filename, the_arena_controller, and ArenaController::tournament_filename.

Here is the call graph for this function:

ArenaRealTime::~ArenaRealTime  )  [virtual]
 

Definition at line 73 of file ArenaRealTime.cc.

References LOG_FILE, robots_in_sequence, and use_log_file.

00074 {
00075   for(int i=0; i < sequences_in_tournament; i++)
00076     delete [] robots_in_sequence[i];
00077 
00078   if( robots_in_sequence != NULL )
00079     delete robots_in_sequence;
00080 
00081   if( use_log_file && LOG_FILE ) LOG_FILE.close();
00082   if( use_message_file && message_file ) message_file.close();
00083 }


Member Function Documentation

void ArenaRealTime::add_cookie  )  [private]
 

Definition at line 521 of file ArenaRealTime.cc.

References Options::get_d(), Shape::get_id(), get_random_position(), List< T >::insert_last(), OPTION_COOKIE_MAX_ENERGY, OPTION_COOKIE_MIN_ENERGY, OPTION_COOKIE_RADIUS, print_to_logfile(), ArenaBase::space_available(), and the_opts.

Referenced by timeout_function().

00522 {
00523   double en = the_opts.get_d(OPTION_COOKIE_MIN_ENERGY) + 
00524     (the_opts.get_d(OPTION_COOKIE_MAX_ENERGY) - the_opts.get_d(OPTION_COOKIE_MIN_ENERGY)) * 
00525     (double)rand() / (double)RAND_MAX;
00526   bool found_space = false;
00527   double r = the_opts.get_d(OPTION_COOKIE_RADIUS);
00528   Vector2D pos;
00529 
00530   for( int i=0; i<100 && !found_space; i++ )
00531     {
00532       pos = get_random_position();
00533       found_space = space_available(pos, r*2.0);
00534     }
00535   
00536   if( !found_space ) return;
00537 
00538   Cookie* cookiep = new Cookie(pos, en);
00539   object_lists[COOKIE].insert_last( cookiep );
00540 
00541   print_to_logfile('C', cookiep->get_id(), pos[0], pos[1]);
00542 }

Here is the call graph for this function:

void ArenaRealTime::add_mine  )  [private]
 

Definition at line 545 of file ArenaRealTime.cc.

References Options::get_d(), Shape::get_id(), get_random_position(), List< T >::insert_last(), OPTION_MINE_MAX_ENERGY, OPTION_MINE_MIN_ENERGY, OPTION_MINE_RADIUS, print_to_logfile(), ArenaBase::space_available(), and the_opts.

Referenced by timeout_function().

00546 {
00547   double en = the_opts.get_d(OPTION_MINE_MIN_ENERGY) + 
00548     (the_opts.get_d(OPTION_MINE_MAX_ENERGY) - the_opts.get_d(OPTION_MINE_MIN_ENERGY)) * 
00549     (double)rand() / (double)RAND_MAX;
00550   bool found_space = false;
00551   double r = the_opts.get_d(OPTION_MINE_RADIUS);
00552   Vector2D pos;
00553 
00554   for( int i=0; i<100 && !found_space; i++)
00555     {
00556       pos = get_random_position();
00557       found_space = space_available(pos, r*2.0);
00558     }
00559   
00560   if( !found_space )  return;
00561 
00562   Mine* minep = new Mine(pos, en);
00563   object_lists[MINE].insert_last( minep );
00564 
00565   print_to_logfile('M', minep->get_id(), pos[0], pos[1]);
00566 }

Here is the call graph for this function:

void ArenaRealTime::broadcast enum  message_to_robot_type...  ) 
 

Referenced by end_game(), set_debug_level(), start_game(), and update_robots().

void ArenaRealTime::check_initialization  )  [private]
 

void ArenaRealTime::check_robots  )  [private]
 

Definition at line 569 of file ArenaRealTime.cc.

References List< T >::first(), Options::get_d(), next_check_time, ListIterator< T >::ok(), OPTION_CHECK_INTERVAL, and the_opts.

Referenced by timeout_function().

00570 {
00571   ListIterator<Robot> li;
00572   for( all_robots_in_sequence.first(li); li.ok(); li++ )
00573     {
00574       if( li()->is_process_running() )
00575         {
00576           li()->check_process();
00577         }      
00578     } 
00579 
00580   next_check_time = total_time + the_opts.get_d(OPTION_CHECK_INTERVAL);
00581 }

Here is the call graph for this function:

void ArenaRealTime::clear  ) 
 

Definition at line 87 of file ArenaRealTime.cc.

References ArenaBase::delete_lists(), NOT_STARTED, robots_in_sequence, and ArenaBase::set_state().

Referenced by start_tournament().

00088 {
00089   delete_lists(true, true, true, true);
00090 
00091   for(int i=0; i < sequences_in_tournament; i++)
00092     delete [] robots_in_sequence[i];
00093 
00094   sequence_nr = 0;
00095   sequences_in_tournament = 0;
00096   
00097   set_state( NOT_STARTED );
00098 }

Here is the call graph for this function:

double ArenaRealTime::colour_dist const long int  col1,
const long int  col2
[private]
 

void ArenaRealTime::end_game  )  [virtual]
 

Implements ArenaBase.

Definition at line 853 of file ArenaRealTime.cc.

References broadcast(), ArenaBase::delete_lists(), Robot::die(), end_sequence(), List< T >::first(), GAME_FINISHES, Robot::is_alive(), Robot::is_dead_but_stats_not_set(), ListIterator< T >::ok(), Robot::set_stats(), and start_game().

Referenced by timeout_function().

00854 {
00855   Robot* robotp;
00856   ListIterator<Robot> li;
00857 
00858   int robots_died_by_timeout = robots_left;
00859   robots_left = 0;
00860 
00861   for( all_robots_in_sequence.first(li); li.ok(); li++ )
00862     {
00863       robotp = li();
00864       if( robotp->is_alive() || robotp->is_dead_but_stats_not_set() )
00865         {
00866           robotp->die();
00867           robotp->set_stats(robots_died_by_timeout, true);
00868         }
00869     }
00870 
00871   broadcast(GAME_FINISHES);
00872 
00873   delete_lists(false, false, false, false);
00874   
00875   if(game_nr == games_per_sequence) 
00876     end_sequence();
00877   else
00878     start_game();
00879 }

Here is the call graph for this function:

void ArenaRealTime::end_sequence  )  [private, virtual]
 

Implements ArenaBase.

Definition at line 966 of file ArenaRealTime.cc.

References List< T >::first(), next_check_time, ListIterator< T >::ok(), ArenaBase::set_state(), and SHUTTING_DOWN_ROBOTS.

Referenced by end_game().

00967 {
00968   // kill all robot processes
00969 
00970   ListIterator<Robot> li;
00971   for( all_robots_in_sequence.first(li); li.ok(); li++ )
00972     {
00973       li()->end_process();
00974     }
00975 
00976   // wait a second before checking
00977 
00978   set_state( SHUTTING_DOWN_ROBOTS);
00979   next_check_time = total_time + 1.0;
00980 }

Here is the call graph for this function:

void ArenaRealTime::end_sequence_follow_up  )  [private]
 

Definition at line 983 of file ArenaRealTime.cc.

References Robot::delete_pipes(), end_tournament(), List< T >::first(), Robot::is_process_running(), Robot::kill_process_forcefully(), ListIterator< T >::ok(), List< T >::remove(), and start_sequence().

Referenced by timeout_function().

00984 {
00985   // check if the process have stopped, otherwise kill
00986   
00987   Robot* robotp;
00988 
00989   ListIterator<Robot> li;
00990   for( all_robots_in_sequence.first(li); li.ok(); li++ )
00991     {
00992       robotp = li();
00993       if( robotp->is_process_running() ) robotp->kill_process_forcefully();
00994       robotp->delete_pipes();
00995       all_robots_in_sequence.remove(li);
00996     }
00997 
00998   if( sequence_nr == sequences_in_tournament ) 
00999     end_tournament();
01000   else
01001     start_sequence();
01002 }

Here is the call graph for this function:

void ArenaRealTime::end_tournament  )  [private, virtual]
 

Implements ArenaBase.

Definition at line 1165 of file ArenaRealTime.cc.

References Gui::close_arenawindow(), FINISHED, ArenaBase::set_state(), and the_gui.

Referenced by end_sequence_follow_up().

01166 {
01167   set_state( FINISHED );
01168 
01169 #ifndef NO_GRAPHICS
01170   if( !no_graphics )
01171     {
01172       //      if( !use_message_file )
01173       //        the_gui.close_messagewindow();
01174       //      the_gui.close_scorewindow();
01175       the_gui.close_arenawindow();
01176     }
01177 #endif
01178 }

Here is the call graph for this function:

long int ArenaRealTime::find_free_colour const long int  home_colour,
const long int  away_colour,
const class Robot ,
const bool  random_colours = false
 

Referenced by start_sequence_follow_up().

List<String> ArenaRealTime::get_arena_filenames  )  [inline]
 

Definition at line 59 of file ArenaRealTime.h.

00059 { return arena_filenames; }

int ArenaRealTime::get_current_arena_nr  )  [inline]
 

Definition at line 60 of file ArenaRealTime.h.

00060 { return current_arena_nr; }

int ArenaRealTime::get_max_debug_level  )  [inline]
 

Definition at line 64 of file ArenaRealTime.h.

00064 { return max_debug_level; }

Vector2D ArenaRealTime::get_random_position  ) 
 

Definition at line 344 of file ArenaRealTime.cc.

Referenced by add_cookie(), add_mine(), and start_game().

00345 {
00346   return Vector2D( boundary[0][0] + (boundary[1][0] - boundary[0][0])*
00347                    (double)rand()/(double)RAND_MAX, 
00348                    boundary[0][1] + (boundary[1][1] - boundary[0][1])*
00349                    (double)rand()/(double)RAND_MAX );
00350 }

bool ArenaRealTime::get_use_message_file  )  [inline]
 

Definition at line 57 of file ArenaRealTime.h.

00057 { return use_message_file; }

bool ArenaRealTime::is_colour_allowed const long int  col,
const double  min_dist,
const class Robot
[private]
 

void ArenaRealTime::parse_arena_file String filename  ) 
 

Definition at line 170 of file ArenaRealTime.cc.

References String::chars(), Error(), Options::get_d(), OPTION_ARENA_SCALE, ArenaBase::parse_arena_line(), print_to_logfile(), and the_opts.

Referenced by start_game().

00171 {
00172   Vector2D vec1, vec2, vec0;
00173 
00174   ifstream file(filename.chars());
00175   if( !file ) Error(true, "Couldn't open arena file" + filename, "ArenaBase::parse_arena_file");
00176 
00177   int succession = 1;
00178   double scale = the_opts.get_d(OPTION_ARENA_SCALE);
00179   double angle_factor = 1.0;
00180   do
00181     {
00182       parse_arena_line(file, scale, succession, angle_factor);
00183 
00184     } while( !file.eof() );
00185 
00186   file.close();
00187 
00188   
00189   if( use_log_file )      // copy the arena file to the log file
00190     {
00191       char buffer[500];
00192       
00193       ifstream file(filename.chars());
00194       if( !file ) Error(true, "Couldn't open arena file for log file" + filename, "ArenaBase::parse_arena_file");
00195   
00196       do
00197         {
00198           file >> ws;
00199           file.get(buffer, 500, '\n');
00200           if( buffer[0] != '\0' ) print_to_logfile('A', buffer);
00201         } 
00202       while( buffer[0] != '\0' );
00203       
00204     }
00205 
00206 }

Here is the call graph for this function:

void ArenaRealTime::print_to_logfile const char  first_letter...  ) 
 

Definition at line 209 of file ArenaRealTime.cc.

References String::chars(), Error(), hex2str(), LOG_FILE, and update_count_for_logging.

Referenced by add_cookie(), add_mine(), parse_arena_file(), start_game(), start_sequence_follow_up(), start_tournament(), and update().

00210 {
00211   if( !use_log_file ) return;
00212 
00213   va_list args;
00214   va_start(args, first_letter);
00215 
00216   // log 'R' only each OPTION_LOG_EVERY_NTH_UPDATE_INTERVAL
00217   if( update_count_for_logging != 0 && first_letter == 'R' )
00218     {
00219       va_end(args);
00220       return;
00221     }
00222 
00223   LOG_FILE << first_letter;
00224 
00225   int prec = 2;
00226   LOG_FILE << setiosflags(ios::fixed) << setprecision(prec);
00227 
00228   switch(first_letter)
00229     {
00230     case 'R': // Robot position info
00231       LOG_FILE << va_arg(args, int   ) << " ";     // robot id;
00232       LOG_FILE << va_arg(args, double) << " ";  // x
00233       LOG_FILE << va_arg(args, double) << " ";  // y
00234       LOG_FILE << va_arg(args, double) << " ";  // robot angle
00235       LOG_FILE << va_arg(args, double) << " ";  // cannon angle
00236       LOG_FILE << va_arg(args, double) << " ";  // radar angle
00237       LOG_FILE << va_arg(args, double);         // energy
00238       break;
00239 
00240     case 'T': // Time
00241       LOG_FILE << setprecision(prec+1) << va_arg(args, double);  // time elapsed
00242       break;
00243 
00244     case 'P': // Print a robot message
00245       LOG_FILE << va_arg(args, int   ) << " ";  // robot id
00246       LOG_FILE << va_arg(args, char* );         // message to print
00247       break;
00248 
00249     case 'C': // Cookie
00250       LOG_FILE << va_arg(args, int   ) << " ";  // cookie id
00251       LOG_FILE << va_arg(args, double) << " ";  // x
00252       LOG_FILE << va_arg(args, double);         // y
00253       break;
00254 
00255     case 'M': // Mine
00256       LOG_FILE << va_arg(args, int   ) << " ";  // mine id
00257       LOG_FILE << va_arg(args, double) << " ";  // x
00258       LOG_FILE << va_arg(args, double);         // y
00259       break;
00260 
00261     case 'S': // Shot
00262       LOG_FILE << va_arg(args, int   ) << " ";  // shot id
00263       LOG_FILE << va_arg(args, double) << " ";  // x
00264       LOG_FILE << va_arg(args, double) << " ";  // y
00265       LOG_FILE << setprecision(prec+1) << va_arg(args, double) << " ";  // dx/dt
00266       LOG_FILE << setprecision(prec+1) << va_arg(args, double);         // dy/dt
00267       break;
00268       
00269     case 'D': // Die
00270       {
00271         int obj_type = va_arg(args, int  );
00272         LOG_FILE << (char)obj_type    << " ";  // object type to kill
00273         LOG_FILE << va_arg(args, int) << " ";  // object id
00274         if( obj_type == 'R' )
00275           {
00276             LOG_FILE << setprecision(1) 
00277                      <<  va_arg(args, double) << " "; // robot points received
00278             LOG_FILE << va_arg(args, int);            // position this game
00279           }
00280       }
00281       break;
00282 
00283     case 'G': // Game begins
00284       LOG_FILE << va_arg(args, int  ) << " ";  // sequence number
00285       LOG_FILE << va_arg(args, int  ) << " ";  // game number
00286       //      LOG_FILE << va_arg(args, char*);         // arena filename
00287       break;
00288 
00289     case 'H': // Header
00290       LOG_FILE << va_arg(args, int  ) << " ";  // number of games per sequence
00291       LOG_FILE << va_arg(args, int  ) << " ";  // number of robots per sequence
00292       LOG_FILE << va_arg(args, int  ) << " ";  // number of sequences
00293       LOG_FILE << va_arg(args, int  ) << " ";  // number of robots
00294       //      LOG_FILE << va_arg(args, char*);         // name of optionfile
00295       break;
00296 
00297     case 'L': // List of robot properties
00298       {
00299         LOG_FILE << va_arg(args, int  ) << " ";  // robot id
00300         LOG_FILE << hex2str(va_arg(args, long )) << " ";  // robot colour
00301        
00302         String name = va_arg(args, char*);   // robot name
00303         if( name == "" ) name = "Anonymous";
00304         LOG_FILE << name;
00305       }
00306       break;
00307 
00308     case 'A': // Arena file line
00309       LOG_FILE << va_arg(args, char*);  // line of arena file
00310       break;
00311 
00312     case 'O':
00313       {
00314         char option_type = (char)va_arg(args, int);
00315         LOG_FILE << va_arg(args, char*);                        // Option label
00316         switch( option_type )
00317           {
00318           case 'D':
00319             LOG_FILE << String( va_arg(args, double) ).chars(); // Option value
00320             break;
00321           case 'L':
00322             LOG_FILE << String( va_arg(args, long) ).chars();   // Option value
00323             break;
00324           case 'H':
00325             LOG_FILE << hex2str( va_arg(args, long) ).chars();   // Option value
00326             break;
00327           case 'S':
00328             LOG_FILE << String( va_arg(args, char*) ).chars();   // Option value
00329             break;
00330           }
00331       }
00332       break;
00333 
00334     default:
00335       Error(true, "Unrecognized first letter in logfile", "ArenaRealTime::print_to_logfile");
00336       break;
00337     }
00338 
00339   LOG_FILE << endl;
00340   va_end(args);
00341 }

Here is the call graph for this function:

void ArenaRealTime::quit_ordered  ) 
 

Definition at line 389 of file ArenaRealTime.cc.

References EXITING, and ArenaBase::set_state().

00390 {
00391   set_state( EXITING );
00392 }

Here is the call graph for this function:

void ArenaRealTime::read_robot_messages  )  [private]
 

Definition at line 584 of file ArenaRealTime.cc.

References List< T >::first(), and ListIterator< T >::ok().

Referenced by timeout_function(), and update().

00585 {
00586   ListIterator<Robot> li;
00587   for( all_robots_in_sequence.first(li); li.ok(); li++ )
00588     {
00589       if( li()->is_alive() || state != GAME_IN_PROGRESS )  
00590         li()->get_messages();
00591     }
00592 }

Here is the call graph for this function:

int ArenaRealTime::set_debug_level const int  new_level  )  [virtual]
 

Reimplemented from ArenaBase.

Definition at line 733 of file ArenaRealTime.cc.

References broadcast(), DEBUG_LEVEL, GAME_OPTION, and ArenaBase::set_debug_level().

00734 {
00735   ArenaBase::set_debug_level(new_level);
00736 
00737   if( GAME_IN_PROGRESS )
00738     {
00739       broadcast(GAME_OPTION, DEBUG_LEVEL, (double)debug_level);
00740     }
00741 
00742   return debug_level;
00743 }

Here is the call graph for this function:

void ArenaRealTime::set_filenames String log_fname,
const String statistics_fname,
const String tournament_fname,
String message_fname,
const String option_fname
 

Definition at line 101 of file ArenaRealTime.cc.

References String::chars(), Error(), LOG_FILE, tournament_file_name, and use_log_file.

Referenced by ArenaRealTime().

00106 {
00107   bool log_stdout = false;
00108 
00109   if( log_fname == "" )
00110     {
00111       use_log_file = false;
00112     }
00113   else if( log_fname == "-" || log_fname == "STDOUT" )  // use stdout as log_file
00114     {
00115       cout << "Attach -- Muss gefixt werden in ArenaREaltime.cc 113" << endl;
00116       //LOG_FILE.attach(STDOUT_FILENO);
00117       use_log_file = true;
00118       log_stdout = true;
00119     }
00120   else
00121     {
00122        //LOG_FILE.open(log_fname.chars(), ios::out, S_IRUSR | S_IWUSR);
00123                 LOG_FILE.open(log_fname.chars(), ios::out);
00124                 
00125       use_log_file = true;
00126       if( !LOG_FILE )
00127         {
00128           Error( false, "Couldn't open log file. Contuing without log file",
00129                  "ArenaRealTime::set_filenames" );
00130           use_log_file = false;
00131         }
00132     }
00133   if( message_fname == "" )
00134     {
00135       use_message_file = false;
00136     }
00137   else if( message_fname == "-" || message_fname == "STDOUT" )
00138     {
00139       if( !log_stdout )
00140         {
00141           use_message_file = true;
00142           //message_file.attach( STDOUT_FILENO );
00143         }
00144       else
00145         {
00146           use_message_file = false;
00147         }
00148     }
00149   else
00150     {
00151       use_message_file = true;
00152       //message_file.open( message_fname.chars(), ios::out, S_IRUSR | S_IWUSR );
00153       if( !message_file )
00154         {
00155           Error( false, "Couldn't open message file. Message file disabled",
00156                  "ArenaRealTime::set_filenames" );
00157           use_message_file = false;
00158         }
00159       
00160     }
00161 
00162   statistics_file_name = statistics_fname;
00163 
00164   tournament_file_name = tournament_fname;
00165 
00166   option_file_name = option_fname;
00167 }

Here is the call graph for this function:

void ArenaRealTime::start_game  )  [private, virtual]
 

Implements ArenaBase.

Definition at line 746 of file ArenaRealTime.cc.

References _, BEFORE_GAME_START, broadcast(), Options::broadcast_opts(), ArenaWindow::clear_area(), current_arena_nr, ArenaWindow::drawing_area_scale_changed(), Error(), String::find(), List< T >::first(), GAME_IN_PROGRESS, GAME_STARTS, Gui::get_arenawindow_p(), Options::get_d(), Robot::get_messages(), List< T >::get_nth(), get_random_position(), Gui::get_scorewindow_p(), get_segment(), List< T >::insert_last(), Robot::live(), Robot::move(), next_check_time, number_of_arenas, ListIterator< T >::ok(), OPTION_CHECK_INTERVAL, OPTION_ROBOT_RADIUS, parse_arena_file(), PAUSING_BETWEEN_GAMES, ArenaBase::print_message(), print_to_logfile(), ArenaBase::reset_timer(), ROBOTS_LEFT, Robot::send_signal(), ArenaBase::set_state(), Robot::set_values_before_game(), ArenaWindow::set_window_title(), ScoreWindow::set_window_title(), ArenaBase::space_available(), the_gui, the_opts, update_count_for_logging, and ScoreWindow::update_robots().

Referenced by end_game(), start_sequence_follow_up(), and timeout_function().

00747 {
00748   // put the arena together
00749 
00750   if( pause_after_next_game )
00751     {
00752       set_state( PAUSING_BETWEEN_GAMES );
00753       return;
00754     }  
00755   
00756   current_arena_nr = current_arena_nr % number_of_arenas + 1;
00757   
00758   String* filename = arena_filenames.get_nth(current_arena_nr);
00759 
00760   print_to_logfile('G', sequence_nr, game_nr + 1);
00761 
00762   parse_arena_file(*filename);
00763 
00764   int charpos;
00765   if( (charpos = filename->find('/',0,true)) != -1 )
00766     current_arena_filename = get_segment(*filename, charpos+1, -1);
00767   else
00768     Error(true, "Incomplete arena file path" + *filename, "ArenaRealTime::start_game");
00769 
00770   char msg[128];
00771   snprintf( msg, 127, _("Game %d of sequence %d begins on arena"),
00772             game_nr+1, sequence_nr );
00773   print_message( "RealTimeBattle", String(msg) + " " + current_arena_filename );
00774 
00775   // reset some variables
00776 
00777   shot_count = 0;
00778   cookie_count = 0;
00779   mine_count = 0;
00780 
00781 
00782   // Place robots on the arena
00783 
00784   Robot* robotp;
00785   bool found_space;
00786   double angle;
00787   Vector2D pos;
00788 
00789   robots_left = 0;
00790   
00791   set_state( BEFORE_GAME_START );
00792 
00793   ListIterator<Robot> li;
00794   for( all_robots_in_sequence.first(li); li.ok(); li++ )
00795     {
00796       robotp = li();
00797       robotp->get_messages();
00798 
00799       found_space = false;
00800       for( int i=0; i<100 && !found_space; i++)
00801         {
00802           pos = get_random_position();
00803           found_space = space_available(pos, the_opts.get_d(OPTION_ROBOT_RADIUS)*1.2);
00804         }
00805 
00806       if( !found_space ) Error(true, "Couldn't find space for all robots", "ArenaRealTime::start_game");
00807       angle = ((double)rand())*2.0*M_PI/RAND_MAX;
00808       robotp->set_values_before_game(pos, angle);
00809       object_lists[ROBOT].insert_last(robotp);
00810       robots_left++;
00811       robotp->live();
00812     }
00813 
00814   //  print_to_logfile('G', sequence_nr, games_per_sequence - games_remaining_in_sequence + 1);
00815 
00816   broadcast(GAME_STARTS);
00817   broadcast(ROBOTS_LEFT, robots_left);
00818   the_opts.broadcast_opts();
00819 
00820 
00821   update_count_for_logging = 0;
00822   print_to_logfile('T', 0.0);
00823 
00824   ListIterator<Shape> li2;
00825   for( object_lists[ROBOT].first(li2); li2.ok(); li2++ )
00826     {
00827       robotp = (Robot*)li2();
00828       robotp->send_signal();
00829       robotp->move(0.0);  // To log current position
00830     }
00831 
00832   set_state( GAME_IN_PROGRESS );
00833   game_nr++;
00834 
00835 #ifndef NO_GRAPHICS
00836   if( !no_graphics )
00837     {
00838       the_gui.get_arenawindow_p()->clear_area();
00839       the_gui.get_arenawindow_p()->drawing_area_scale_changed();
00840       the_gui.get_scorewindow_p()->update_robots();
00841 
00842       reset_timer();  // Time should be zero in score window
00843       the_gui.get_scorewindow_p()->set_window_title();
00844       the_gui.get_arenawindow_p()->set_window_title();
00845     }
00846 #endif
00847 
00848   reset_timer();  // Game starts !
00849   next_check_time = total_time + the_opts.get_d(OPTION_CHECK_INTERVAL);
00850 }

Here is the call graph for this function:

void ArenaRealTime::start_sequence  )  [private, virtual]
 

Implements ArenaBase.

Definition at line 883 of file ArenaRealTime.cc.

References current_arena_nr, List< T >::first(), Options::get_d(), Robot::get_outstreamp(), Robot::is_networked(), next_check_time, ListIterator< T >::ok(), OPTION_ROBOT_STARTUP_TIME, ArenaBase::reset_timer(), robots_in_sequence, ArenaBase::set_state(), Robot::set_values_at_process_start_up(), Robot::start_process(), STARTING_ROBOTS, and the_opts.

Referenced by end_sequence_follow_up(), and start_tournament().

00884 {
00885   game_nr = 0;
00886   current_arena_nr = 0;
00887 
00888   // Make list of robots in this sequence
00889 
00890   for(int i=0; i<robots_per_game; i++)
00891     {
00892       all_robots_in_sequence.
00893         insert_last( all_robots_in_tournament.
00894                      get_nth(robots_in_sequence[sequence_nr][i]));
00895     }
00896 
00897   // execute robot processes
00898 
00899 
00900   Robot* robotp;
00901   ListIterator<Robot> li;
00902   for( all_robots_in_sequence.first(li); li.ok(); li++ )
00903     {
00904       robotp = li();
00905       if( robotp->is_networked() )
00906         {
00907           *robotp->get_outstreamp() << "@R" << endl;
00908           robotp->set_values_at_process_start_up();
00909         }      
00910       else
00911         robotp->start_process();
00912     }
00913   
00914   // wait a second before checking
00915 
00916   set_state( STARTING_ROBOTS );
00917   sequence_nr++;
00918   reset_timer();
00919   next_check_time = total_time + the_opts.get_d(OPTION_ROBOT_STARTUP_TIME);
00920 }

Here is the call graph for this function:

void ArenaRealTime::start_sequence_follow_up  )  [private]
 

Definition at line 923 of file ArenaRealTime.cc.

References _, String::chars(), COLOUR_NOT_GIVEN, find_free_colour(), List< T >::first(), Shape::get_id(), Shape::get_rgb_colour(), Robot::get_robot_filename(), Robot::get_robot_name(), Robot::is_colour_given(), Robot::is_name_given(), Robot::is_networked(), Robot::is_process_running(), NAME_NOT_GIVEN, ListIterator< T >::ok(), ArenaBase::print_message(), print_to_logfile(), List< T >::remove(), Robot::send_message(), Robot::set_and_get_has_competed(), Shape::set_colour(), Robot::set_colour_given(), start_game(), and WARNING.

Referenced by timeout_function().

00924 {
00925   // check if the process have started correctly
00926   Robot* robotp = NULL;
00927 
00928   ListIterator<Robot> li;
00929   for( all_robots_in_sequence.first(li); li.ok(); li++ )
00930     {
00931       robotp = li();
00932       if( !(robotp->is_networked()) &&
00933           !(robotp->is_process_running()) ) 
00934         {
00935           all_robots_in_sequence.remove(li);
00936           robots_left--;
00937         }
00938       else
00939         {      
00940           if( !robotp->set_and_get_has_competed() )
00941             print_to_logfile('L', robotp->get_id(), robotp->get_rgb_colour(), 
00942                              robotp->get_robot_name().chars());
00943           
00944           if( !robotp->is_name_given() )
00945             {
00946               robotp->send_message(WARNING, NAME_NOT_GIVEN, "");
00947               char msg[128];
00948               snprintf( msg, 127, _("Robot with filename %s has not given any name"),
00949                         robotp->get_robot_filename().chars() );
00950               print_message( "RealTimeBattle", String(msg) );
00951             }
00952 
00953           if( !robotp->is_colour_given() )
00954             {
00955               robotp->send_message(WARNING, COLOUR_NOT_GIVEN, "");
00956               robotp->set_colour( find_free_colour( 0, 0, robotp, true ) );
00957               robotp->set_colour_given( true );
00958             }
00959         }
00960 
00961     }
00962   start_game();
00963 }

Here is the call graph for this function:

void ArenaRealTime::start_tournament const List< start_tournament_info_t > &  robotfilename_list,
const List< start_tournament_info_t > &  arenafilename_list,
const int  robots_p_game,
const int  games_p_sequence,
const int  n_o_sequences
 

Definition at line 1017 of file ArenaRealTime.cc.

References binomial(), clear(), MessageWindow::clear_clist(), Error(), start_tournament_info_t::filename, List< T >::first(), Gui::get_messagewindow_p(), Timer::get_random_seed(), List< T >::insert_last(), Gui::is_arenawindow_up(), Gui::is_messagewindow_up(), Gui::is_scorewindow_up(), Options::log_all_options(), number_of_arenas, ListIterator< T >::ok(), Gui::open_arenawindow(), Gui::open_messagewindow(), Gui::open_scorewindow(), print_to_logfile(), reorder_pointer_array(), robots_in_sequence, start_sequence(), the_gui, and the_opts.

01022 {
01023   clear();
01024 
01025   // Open windows if they were closed, else clear them 
01026 
01027 #ifndef NO_GRAPHICS
01028   if( !no_graphics )
01029     {
01030       if( the_gui.is_messagewindow_up() )
01031         MessageWindow::clear_clist( NULL, the_gui.get_messagewindow_p() );
01032       else //if( !use_message_file )
01033         the_gui.open_messagewindow();
01034 
01035       if( !the_gui.is_scorewindow_up() ) the_gui.open_scorewindow();
01036       if( !the_gui.is_arenawindow_up() ) the_gui.open_arenawindow();
01037     }
01038 #endif
01039 
01040   // Create robot classes and put them into the list all_robots_in_tournament
01041 
01042   number_of_robots = 0;
01043   robot_count = 0;
01044   Robot* robotp;
01045   start_tournament_info_t* infop = NULL;
01046   String* stringp;
01047 
01048   ListIterator<start_tournament_info_t> li;
01049   for( robotfilename_list.first(li); li.ok(); li++ )
01050     {
01051       infop = li();
01052       robotp = new Robot(infop->filename);
01053       all_robots_in_tournament.insert_last( robotp );
01054       number_of_robots++;
01055     }
01056 
01057   // Create list of arena filenames
01058   number_of_arenas = 0;
01059   
01060   for( arenafilename_list.first(li); li.ok(); li++ )
01061     {
01062       stringp = new String(li()->filename);
01063       arena_filenames.insert_last( stringp );
01064       number_of_arenas++;
01065     }
01066 
01067   robots_per_game = robots_p_game;
01068   games_per_sequence = games_p_sequence;
01069   sequences_in_tournament = n_o_sequences;
01070 
01071   // make list of robots to compete in the sequences
01072   int games_per_round = binomial(number_of_robots, robots_per_game);
01073   int complete_rounds = n_o_sequences / games_per_round;
01074   int rem_games = n_o_sequences % games_per_round;
01075 
01076   robots_in_sequence = new (int*)[n_o_sequences];
01077   for(int i=0; i<n_o_sequences; i++) robots_in_sequence[i] = new int[robots_per_game];
01078   
01079   int current_sequence[robots_per_game];
01080   int current_nr = 0;
01081   //  for(int i=0; i<robots_per_game; i++) current_sequence[i] = i+1;
01082   
01083   // set complete rounds first
01084 
01085   for(int round_nr=0; round_nr < complete_rounds; round_nr++)
01086     {
01087       int k, i, j;
01088 
01089       for(i=0; i<robots_per_game; i++) current_sequence[i] = i+1;
01090       current_sequence[robots_per_game-1]--;   // To be increased first time
01091 
01092       
01093       for(i=0; i< games_per_round; i++)
01094         {
01095           
01096           k = robots_per_game - 1;
01097           while( current_sequence[k] == number_of_robots + 1 - robots_per_game + k )
01098             k--;
01099 
01100           if( k < 0 ) Error(true, "Problem generating list of participants, k < 0", 
01101                             "ArenaRealTime::start_tournament");
01102 
01103           current_sequence[k]++;
01104           for(j=k+1; j<robots_per_game; j++) current_sequence[j] = current_sequence[j-1]+1;
01105 
01106           for(j=0; j<robots_per_game; j++) 
01107             robots_in_sequence[current_nr][j] = current_sequence[j];
01108 
01109           current_nr++;
01110         }
01111       reorder_pointer_array((void**)robots_in_sequence, games_per_round);
01112     }
01113 
01114   // the remaining game will be randomly chosen
01115 
01116   int robot_matches_played[number_of_robots];
01117   for(int i=0; i<number_of_robots; i++) robot_matches_played[i] = 0;
01118 
01119   bool robot_playing_this_match[number_of_robots];
01120   int min_matches_played = 0;
01121   int number_of_robots_on_min_matches = number_of_robots;
01122   int nr;
01123 
01124   for(int i=0; i< rem_games; i++)
01125     {
01126       for(int i2=0; i2<number_of_robots; i2++) robot_playing_this_match[i2] = false;
01127 
01128       for(int j=0; j<robots_per_game; j++)
01129         {
01130           do 
01131             nr = (int)floor(number_of_robots*((double)rand() / (double)RAND_MAX));
01132           while( robot_playing_this_match[nr] || robot_matches_played[nr] != min_matches_played );
01133 
01134           robot_playing_this_match[nr] = true;
01135           robot_matches_played[nr]++;
01136           number_of_robots_on_min_matches--;
01137           if( number_of_robots_on_min_matches == 0 ) 
01138             {
01139               min_matches_played++;
01140               number_of_robots_on_min_matches = number_of_robots;
01141             }
01142 
01143           robots_in_sequence[current_nr][j] = nr + 1;   // robot count will start from 1
01144         }      
01145       current_nr++;
01146     }
01147 
01148   // set random seed
01149 
01150 
01151   srand(timer.get_random_seed());
01152 
01153   // start first sequence
01154 
01155   print_to_logfile('H', games_per_sequence, robots_per_game, 
01156                    sequences_in_tournament, number_of_robots);
01157 
01158   the_opts.log_all_options();
01159 
01160   sequence_nr = 0;
01161   start_sequence();
01162 }

Here is the call graph for this function:

void ArenaRealTime::start_tournament_from_tournament_file const List< start_tournament_info_t > &  robotfilename_list,
const List< start_tournament_info_t > &  arenafilename_list,
const int  robots_p_game,
const int  games_p_sequence,
const int  n_o_sequences,
ArenaRealTime ar_p
[static]
 

Definition at line 1006 of file ArenaRealTime.cc.

Referenced by timeout_function().

01010 {
01011   ar_p->start_tournament( robotfilename_list, arenafilename_list, robots_p_game,
01012                           games_p_sequence, n_o_sequences );
01013 }

bool ArenaRealTime::timeout_function  )  [virtual]
 

Implements ArenaBase.

Definition at line 395 of file ArenaRealTime.cc.

References add_cookie(), add_mine(), ArenaController::auto_start_and_end, BEFORE_GAME_START, check_robots(), end_game(), end_sequence_follow_up(), Error(), EXITING, FINISHED, List< T >::first(), GAME_IN_PROGRESS, Options::get_d(), Gui::get_scorewindow_p(), NO_STATE, NOT_STARTED, ListIterator< T >::ok(), OPTION_COOKIE_FREQUENCY, OPTION_MINE_FREQUENCY, OPTION_TIMEOUT, parse_tournament_file(), PAUSED, PAUSING_BETWEEN_GAMES, Quit(), read_robot_messages(), ArenaBase::save_statistics_to_file(), ArenaBase::set_state(), ScoreWindow::set_window_title(), SHUTTING_DOWN_ROBOTS, start_game(), start_sequence_follow_up(), start_tournament_from_tournament_file(), STARTING_ROBOTS, StartTournamentFunction, the_arena_controller, the_gui, the_opts, tournament_file_name, update(), and ArenaBase::update_timer().

00396 {
00397 #ifndef NO_GRAPHICS
00398       int old_total = (int)total_time;
00399 #endif 
00400 
00401   if( state != PAUSED )
00402     {
00403       update_timer ();
00404     }
00405 
00406   switch(state)
00407     {
00408     case NOT_STARTED:
00409       if( the_arena_controller.auto_start_and_end )
00410         parse_tournament_file( tournament_file_name,
00411                                (StartTournamentFunction)
00412                                ArenaRealTime::start_tournament_from_tournament_file,
00413                                this );
00414       break;
00415 
00416     case FINISHED:
00417       if( the_arena_controller.auto_start_and_end )
00418         {
00419           if( statistics_file_name != "" )
00420             save_statistics_to_file( statistics_file_name );
00421 
00422           Quit();
00423         }
00424       break;
00425       
00426     case STARTING_ROBOTS:
00427       {
00428         read_robot_messages();
00429 
00430         if( total_time > next_check_time ) start_sequence_follow_up();
00431       }
00432       break;
00433       
00434     case SHUTTING_DOWN_ROBOTS:
00435       {     
00436         ListIterator<Robot> li;
00437         for( all_robots_in_sequence.first(li); li.ok(); li++ )
00438           li()->get_messages();
00439         
00440         if( total_time > next_check_time ) end_sequence_follow_up();
00441       }
00442       break;
00443       
00444     case GAME_IN_PROGRESS:
00445       {
00446         update();
00447 #ifndef NO_GRAPHICS
00448         if((int)total_time > old_total && !no_graphics)
00449           the_gui.get_scorewindow_p()->set_window_title();
00450 #endif
00451         if( robots_left <= 1 || total_time > the_opts.get_d(OPTION_TIMEOUT) ) 
00452           {
00453             end_game();
00454           }
00455         else
00456           {
00457             if( game_mode == COMPETITION_MODE && total_time > next_check_time ) check_robots();
00458             
00459             // Place mines and cookies
00460             if( ((double)rand()) / (double)RAND_MAX <= timestep*the_opts.get_d(OPTION_COOKIE_FREQUENCY) )
00461               add_cookie();
00462             
00463             if( ((double)rand()) / (double)RAND_MAX <= timestep*the_opts.get_d(OPTION_MINE_FREQUENCY) )
00464               add_mine();
00465 
00466               if( halt_next )
00467                 {
00468                   set_state( PAUSED );
00469                   halt_next = false;
00470                 }
00471           }
00472       }
00473       break;
00474 
00475     case PAUSED:
00476       break;
00477 
00478     case PAUSING_BETWEEN_GAMES:
00479       if( !pause_after_next_game ) start_game();
00480       break;
00481 
00482     case EXITING:
00483       return false;
00484       
00485     case BEFORE_GAME_START:
00486     case NO_STATE:
00487       Error(true, "Arena shouldn't be in this state here!!", "ArenaRealTime::timeout_function");
00488     }
00489 
00490   return true;
00491 }

Here is the call graph for this function:

void ArenaRealTime::update  )  [private, virtual]
 

Implements ArenaBase.

Definition at line 494 of file ArenaRealTime.cc.

References ArenaWindow::draw_moving_objects(), MessageWindow::freeze_clist(), GAME_IN_PROGRESS, Gui::get_arenawindow_p(), Options::get_l(), Gui::get_messagewindow_p(), ArenaBase::move_shots(), OPTION_LOG_EVERY_NTH_UPDATE_INTERVAL, print_to_logfile(), read_robot_messages(), MessageWindow::thaw_clist(), the_gui, the_opts, update_count_for_logging, and update_robots().

Referenced by timeout_function().

00495 {
00496   print_to_logfile('T', total_time);
00497 
00498 #ifndef NO_GRAPHICS
00499   if( state == GAME_IN_PROGRESS && !no_graphics)
00500     the_gui.get_messagewindow_p()->freeze_clist();
00501 #endif
00502 
00503   read_robot_messages();
00504   move_shots(timestep);
00505   update_robots();
00506 
00507 #ifndef NO_GRAPHICS
00508   if( state == GAME_IN_PROGRESS && !no_graphics)
00509     {
00510       the_gui.get_arenawindow_p()->draw_moving_objects( true );
00511       the_gui.get_messagewindow_p()->thaw_clist();
00512     }
00513 #endif
00514 
00515   update_count_for_logging++;
00516   if( update_count_for_logging == the_opts.get_l(OPTION_LOG_EVERY_NTH_UPDATE_INTERVAL) )
00517     update_count_for_logging = 0;
00518 }

Here is the call graph for this function:

void ArenaRealTime::update_robots  )  [private]
 

Definition at line 595 of file ArenaRealTime.cc.

References broadcast(), Robot::change_velocity(), Robot::display_score(), ENERGY, List< T >::first(), Robot::get_energy(), Options::get_l(), Robot::get_messages(), Robot::is_alive(), Robot::move(), ListIterator< T >::ok(), OPTION_ROBOT_ENERGY_LEVELS, List< T >::remove(), ROBOTS_LEFT, Robot::send_message(), the_opts, and Robot::update_radar_and_cannon().

Referenced by update().

00596 {
00597   Robot* robotp;
00598 
00599   robots_killed_this_round = 0;
00600 
00601   ListIterator<Shape> li;
00602   for( object_lists[ROBOT].first(li); li.ok(); li++ )
00603     {
00604       robotp = (Robot*)li();
00605       if( robotp->is_alive() )
00606         {
00607           robotp->update_radar_and_cannon(timestep);  
00608           robotp->change_velocity(timestep);
00609           robotp->move(timestep);        
00610         }
00611       if( robotp->is_alive() ) 
00612         robotp->get_messages();
00613     }
00614 
00615   // Check if robots have died and send energy level
00616 
00617   for( object_lists[ROBOT].first(li); li.ok(); li++ )
00618     {
00619       robotp = (Robot*)li();
00620       if( !robotp->is_alive() ) 
00621         {
00622           object_lists[ROBOT].remove(li);
00623           robots_killed_this_round++;
00624         }
00625       else
00626         {
00627           double lvls = (double)the_opts.get_l(OPTION_ROBOT_ENERGY_LEVELS);
00628           robotp->send_message( ENERGY, rint( robotp->get_energy() / lvls ) * lvls );
00629         }
00630     }
00631 
00632   robots_left -= robots_killed_this_round;
00633 
00634   if( robots_killed_this_round > 0 )
00635     {
00636       for( object_lists[ROBOT].first(li); li.ok(); li++ )
00637         {
00638           robotp = (Robot*)li();
00639           //          robotp->add_points(robots_killed_this_round);
00640 #ifndef NO_GRAPHICS
00641           if( robots_left < 15 && !no_graphics ) 
00642             robotp->display_score();
00643 #endif
00644         }
00645 
00646       ListIterator<Robot> li2;
00647       for( all_robots_in_sequence.first(li2); li2.ok(); li2++ )
00648         if( li2()->is_dead_but_stats_not_set() )
00649           li2()->set_stats(robots_killed_this_round);
00650       
00651       broadcast(ROBOTS_LEFT, robots_left);
00652     }
00653 
00654   
00655   for( object_lists[ROBOT].first(li); li.ok(); li++ )
00656     ((Robot*)li())->send_signal();
00657 }

Here is the call graph for this function:


Field Documentation

int ArenaRealTime::current_arena_nr [private]
 

Definition at line 107 of file ArenaRealTime.h.

Referenced by start_game(), and start_sequence().

ofstream ArenaRealTime::LOG_FILE [private]
 

Definition at line 98 of file ArenaRealTime.h.

Referenced by print_to_logfile(), set_filenames(), and ~ArenaRealTime().

double ArenaRealTime::next_check_time [private]
 

Definition at line 104 of file ArenaRealTime.h.

Referenced by check_robots(), end_sequence(), start_game(), and start_sequence().

int ArenaRealTime::number_of_arenas [private]
 

Definition at line 106 of file ArenaRealTime.h.

Referenced by start_game(), and start_tournament().

int** ArenaRealTime::robots_in_sequence [private]
 

Definition at line 102 of file ArenaRealTime.h.

Referenced by ArenaRealTime(), clear(), start_sequence(), start_tournament(), and ~ArenaRealTime().

String ArenaRealTime::tournament_file_name [private]
 

Definition at line 96 of file ArenaRealTime.h.

Referenced by set_filenames(), and timeout_function().

int ArenaRealTime::update_count_for_logging [private]
 

Definition at line 100 of file ArenaRealTime.h.

Referenced by print_to_logfile(), start_game(), and update().

bool ArenaRealTime::use_log_file [private]
 

Definition at line 99 of file ArenaRealTime.h.

Referenced by set_filenames(), and ~ArenaRealTime().


The documentation for this class was generated from the following files:
Generated on Fri Oct 15 15:49:19 2004 for Real Time Battle by  doxygen 1.3.9.1