/*! 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(); }