Example #1
0
/*! This is the main function and creates and links all the different
    classes.  First it reads in all the parameters from the command
    prompt (<program name> -help)and uses these values to create the
    classes. After all the classes are linked, the mainLoop in the
    Player class is called. */
int main( int argc, char * argv[] )
{
#ifdef WIN32
  HANDLE         listen, sense;
#else
  pthread_t      listen, sense;
#endif
  ServerSettings ss;
  PlayerSettings cs;

  // define variables for command options and initialize with default values
  char     strTeamName[MAX_TEAM_NAME_LENGTH] = "UvA_Trilearn";
  int      iPort                             = 6002;
  int      iMinLogLevel                      = 0 ;
  int      iMaxLogLevel                      = 0;
  char     strHost[128]                      = "localhost";
  double   dVersion                          = 14;
  int      iMode                             = 0;
  char     strFormations[128]                = "formations.conf";
  int      iNr                               = 0;
  int      iReconnect                        = -1;
  bool     bInfo                             = false;
  bool     bSuppliedLogFile                  = false;
  ofstream os;

  // read in all the command options and change the associated variables
  // assume every two values supplied at prompt, form a duo
  char * str;
  for( int i = 1 ; i < argc ; i = i + 2  )
  {
    // help is only option that does not have to have an argument
    if( i + 1 >= argc && strncmp( argv[i], "-help", 3 ) != 0 )
    {
      cout << "Need argument for option: " << argv[i] << endl;
      exit( 0 );
    }
    // read a command option
    if( argv[i][0] == '-' && strlen( argv[i] ) > 1)
    {
      switch( argv[i][1] )
      {
        case 'h':                                   // host server or help
          if( strlen( argv [i]) > 2 && argv[i][2] == 'e' )
          {
            printOptions( );
            exit(0);
          }
          else
            strcpy( strHost, argv[i+1] );
          break;
        case 'f':                                   // formations file
          strcpy( strFormations, argv[i+1] );
          break;
        case 'c':                                   // clientconf file
          if( cs.readValues( argv[i+1], ":" ) == false )
            cerr << "Error in reading client file: " << argv[i+1] << endl;
          break;
        case 'i':                                   // info 1 0
          str   = &argv[i+1][0];
          bInfo = (Parse::parseFirstInt( &str ) == 1 ) ? true : false ;
          break;
        case 'l':                                   // loglevel int[..int]
          str = &argv[i+1][0];
          iMinLogLevel = Parse::parseFirstInt( &str );
          while( iMinLogLevel != 0 )
          {
            if( *str == '.' ) // '.' indicates range of levels
            {
              iMaxLogLevel = Parse::parseFirstInt( &str );
              if( iMaxLogLevel == 0 ) iMaxLogLevel = iMinLogLevel;
              Log.addLogRange( iMinLogLevel, iMaxLogLevel );
            }
            else
              Log.addLogLevel( iMinLogLevel );
            iMinLogLevel = Parse::parseFirstInt( &str );
          }
          break;
        case 'm':                                   // mode int
          str = &argv[i+1][0];
          iMode = Parse::parseFirstInt( &str );
          break;
        case 'o':                                   // output file log info
          os.open( argv[i+1] );
          bSuppliedLogFile = true;
          break;
        case 'p':                                   // port
          str = &argv[i+1][0];
          iPort = Parse::parseFirstInt( &str );
          break;
        case 's':                                   // serverconf file
          if( ss.readValues( argv[i+1], ":" ) == false )
            cerr << "Error in reading server file: " << argv[i+1] << endl;
          break;
        case 't':                                   // teamname name
          strcpy( strTeamName, argv[i+1] );
          break;
        case 'v':                                   // version version
          str = &argv[i+1][0];
          dVersion = Parse::parseFirstDouble( &str );
          break;
        default:
          cerr << "(main) Unknown command option: " << argv[i] << endl;
      }
    }
  }


  if( bInfo == true )
  cout << "team         : "  << strTeamName    << endl <<
          "port         : "  << iPort          << endl <<
          "host         : "  << strHost        << endl <<
          "version      : "  << dVersion       << endl <<
          "min loglevel : "  << iMinLogLevel   << endl <<
          "max loglevel : "  << iMaxLogLevel   << endl <<
          "mode         : "  << iMode          << endl <<
          "playernr     : "  << iNr            << endl <<
          "reconnect    : "  << iReconnect     << endl ;

  if( bSuppliedLogFile == true )
    Log.setOutputStream( os );                   // initialize logger
  else
    Log.setOutputStream( cout );
  Log.restartTimer( );
  Formations fs( strFormations, (FormationT)cs.getInitialFormation(), iNr );
                                               // read formations file
  WorldModel wm( &ss, &cs, &fs );              // create worldmodel
  Connection c( strHost, iPort, MAX_MSG );     // make connection with server
  ActHandler a( &c, &wm, &ss );                // link actHandler and WM
  SenseHandler s( &c, &wm, &ss, &cs );         // link senseHandler with wm
  bool isTrainer = (iPort == ss.getCoachPort()) ? true : false;
  BasicCoach bp( &a, &wm, &ss, strTeamName, dVersion, isTrainer );
                                               // link acthandler and WM

#ifdef WIN32
  DWORD id1;
  sense = CreateThread(NULL, 0, &sense_callback, &s, 0, &id1);
  if (sense == NULL)
  {
      cerr << "create thread error" << endl;
      return false;
  }
#else
  pthread_create( &sense, NULL, sense_callback  , &s); // start listening
#endif

  if( iMode > 0 && iMode < 9 )       // only listen to sdtdin when not playing
#ifdef WIN32
  {
    DWORD id2;
    listen = CreateThread(NULL, 0, &stdin_callback, &bp, 0, &id2);
    if ( listen == NULL)
    {
        cerr << "create thread error" << endl;
        return false;
    }
  }
#else
    pthread_create( &listen, NULL, stdin_callback, &bp);
#endif
  
  if( iMode == 0 )
    bp.mainLoopNormal();

  c.disconnect();
  
  os.close();
}