Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Player.C

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000,2001, Jelle Kok, University of Amsterdam
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without 
00006 modification, are permitted provided that the following conditions are met:
00007 
00008 1. Redistributions of source code must retain the above copyright notice, this 
00009 list of conditions and the following disclaimer. 
00010 
00011 2. Redistributions in binary form must reproduce the above copyright notice, 
00012 this list of conditions and the following disclaimer in the documentation 
00013 and/or other materials provided with the distribution. 
00014 
00015 3. Neither the name of the University of Amsterdam nor the names of its 
00016 contributors may be used to endorse or promote products derived from this 
00017 software without specific prior written permission. 
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00020 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00021 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00022 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
00023 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
00024 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
00025 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
00026 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
00027 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00028 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 */
00044 #include "Player.h"
00045 #include "Parse.h"
00046 #include <sys/poll.h> // needed for 'poll'
00047 
00048 
00058 Player::Player( ActHandler* act, WorldModel *wm, ServerSettings *ss,
00059       PlayerSettings *ps,
00060       Formations *fs, char* strTeamName, double dVersion, int iReconnect )
00061 
00062 {
00063   char str[MAX_MSG];
00064 
00065   ACT          = act;
00066   WM           = wm;
00067   SS           = ss;
00068   PS           = ps;
00069   formations   = fs;
00070   bContLoop    = true;
00071   WM->setTeamName( strTeamName );
00072   m_lastSay    = -1;
00073 
00074   // wait longer as role number increases, to make sure players appear at the
00075   // field in the correct order
00076   poll( 0, 0, formations->getPlayerInFormation()*100 );
00077 
00078   // create initialisation string
00079   if( iReconnect != -1 )
00080     sprintf( str, "(reconnect %s %d)", strTeamName, iReconnect );
00081   else if( formations->getPlayerType() == PT_GOALKEEPER )
00082     sprintf( str, "(init %s (version %f) (goalie))", strTeamName, dVersion );
00083   else
00084     sprintf( str, "(init %s (version %f))", strTeamName, dVersion );
00085   ACT->sendMessage( str );
00086 }
00087 
00092 void Player::mainLoop( )
00093 {
00094   while( bContLoop )                                 // as long as server alive
00095   {
00096     Log.logWithTime( 3, "  start update_all" );
00097 //    Log.setHeader( WM->getCurrentCycle(), WM->getPlayerNumber() );
00098     
00099     if( WM->updateAll( ) == true )
00100     {
00101       if( shallISaySomething() == true )             // shall I communicate
00102       {
00103         m_lastSay = WM->getCurrentCycle();
00104         ACT->sendCommandDirect( sayWorldStatus() );
00105       }
00106 
00107       switch( formations->getPlayerType( ) )        // determine right loop
00108       {
00109         case PT_GOALKEEPER:       goalieMainLoop( );     break;
00110         case PT_DEFENDER_SWEEPER:
00111         case PT_DEFENDER_WING:    defenderMainLoop( );   break;
00112         case PT_MIDFIELDER_CENTER:
00113         case PT_MIDFIELDER_WING:  midfielderMainLoop( ); break;
00114         case PT_ATTACKER:
00115         case PT_ATTACKER_WING:    attackerMainLoop( );   break;
00116         case PT_ILLEGAL:
00117         default: break;
00118       }
00119 
00120       Log.logWithTime( 3, "  determined action; waiting for new info" );
00121 
00122       // directly after see message, will nog get better info, so send commands
00123       if( WM->getTimeLastSeeMessage() == WM->getCurrentTime() )
00124         ACT->sendCommands( );
00125 
00126     }
00127     else
00128       Log.logWithTime( 3, "  HOLE no action determined; waiting for new info" );
00129 
00130     // wait for new information from the server
00131     // cannot say bContLoop=WM->wait... since bContLoop can be changed elsewhere
00132     if(  WM->waitForNewInformation() == false )
00133         bContLoop =  false;
00134   }
00135 
00136   // shutdow, print hole and number of players seen statistics
00137   printf("Shutting down player %d\n", WM->getPlayerNumber() );
00138   printf("   Number of holes: %d (%f)\n", WM->iNrHoles,
00139                          ((double)WM->iNrHoles/WM->getCurrentCycle())*100 );
00140   printf("   Teammates seen: %d (%f)\n", WM->iNrTeammatesSeen,
00141                          ((double)WM->iNrTeammatesSeen/WM->getCurrentCycle()) );
00142   printf("   Opponents seen: %d (%f)\n", WM->iNrOpponentsSeen,
00143                          ((double)WM->iNrOpponentsSeen/WM->getCurrentCycle()) );
00144 
00145 }
00146 
00147 
00149 void Player::goalieMainLoop( )
00150 {
00151   deMeer5_goalie();
00152 }    
00153 
00155 void Player::defenderMainLoop( )
00156 {
00157   deMeer5( );
00158 }
00159 
00161 void Player::midfielderMainLoop( )
00162 {
00163   deMeer5( );
00164 }
00165 
00167 void Player::attackerMainLoop( )
00168 {
00169   deMeer5( );
00170 }
00171 
00182 void Player::deMeer5(  )
00183 {
00184 
00185   SoccerCommand soc(CMD_ILLEGAL);
00186   VecPosition   posAgent = WM->getAgentGlobalPosition();
00187   VecPosition   posBall  = WM->getBallPos();
00188   int           iTmp;
00189 
00190   if( WM->isBeforeKickOff( ) )
00191   {
00192     if( formations->getFormation() != FT_INITIAL || // not in kick_off formation
00193         posAgent.getDistanceTo( getStrategicPosition() ) > 2.0 )  
00194     {
00195       formations->setFormation( FT_INITIAL );       // go to kick_off formation
00196       ACT->putCommandInQueue( teleportToPos( getStrategicPosition() ) );
00197     }
00198     else                                            // else turn to center
00199     {
00200       ACT->putCommandInQueue( turnBodyToPoint( VecPosition( 0, 0 ), 0 ) );
00201       ACT->putCommandInQueue( alignNeckWithBody( ) );
00202     }
00203   }
00204   else
00205   {
00206     formations->setFormation( FT_STANDARD );
00207     soc.commandType = CMD_ILLEGAL;
00208 
00209     if( WM->getConfidence( OBJECT_BALL ) < PS->getBallConfThr() )
00210     {
00211       ACT->putCommandInQueue( searchBall() );         // if ball pos unknown
00212       ACT->putCommandInQueue( alignNeckWithBody( ) ); // search for it
00213     }
00214     else if( WM->isBallKickable())                    // if kickable
00215     {
00216       VecPosition posGoal( PITCH_LENGTH/2.0,
00217               (-1 + 2*(WM->getCurrentCycle()%2)) * 0.4 * SS->getGoalWidth() );
00218       soc = kickTo( posGoal, SS->getBallSpeedMax() ); // kick maximal
00219 
00220       ACT->putCommandInQueue( soc );
00221       ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00222       Log.log( 100, "kick ball" );
00223     }
00224     else if( WM->getFastestInSetTo( OBJECT_SET_TEAMMATES, OBJECT_BALL, &iTmp )
00225               == WM->getAgentObjectType()  && !WM->isDeadBallThem() )
00226     {                                                // if fastest to ball
00227       Log.log( 100, "I am fastest to ball; can get there in %d cycles", iTmp );
00228       soc = intercept( false );                      // intercept the ball
00229 
00230       if( soc.commandType == CMD_DASH &&             // if stamina low
00231           WM->getAgentStamina().getStamina() <
00232              SS->getRecoverDecThr()*SS->getStaminaMax()+200 )
00233       {
00234         soc.dPower = 30.0 * WM->getAgentStamina().getRecovery(); // dash slow
00235         ACT->putCommandInQueue( soc );
00236         ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00237       }
00238       else                                           // if stamina high
00239       {
00240         ACT->putCommandInQueue( soc );               // dash as intended
00241         ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00242       }
00243      }
00244      else if( posAgent.getDistanceTo(getStrategicPosition()) >
00245                   1.5 + fabs(posAgent.getX()-posBall.getX())/10.0)
00246                                                   // if not near strategic pos
00247      {
00248        if( WM->getAgentStamina().getStamina() >     // if stamina high
00249                             SS->getRecoverDecThr()*SS->getStaminaMax()+200 )
00250        {
00251          soc = moveToPos(getStrategicPosition(),PS->getPlayerWhenToTurnAngle());
00252          ACT->putCommandInQueue( soc );            // move to strategic pos
00253          ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00254        }
00255        else                                        // else watch ball
00256        {
00257          ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) );
00258          ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00259        }
00260      }
00261      else if( fabs( WM->getRelativeAngle( OBJECT_BALL ) ) > 1.0 ) // watch ball
00262      {
00263        ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) );
00264        ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00265      }
00266      else                                         // nothing to do
00267        ACT->putCommandInQueue( SoccerCommand(CMD_TURNNECK,0.0) );
00268    }
00269 }
00270 
00271 
00278 void Player::deMeer5_goalie(  )
00279 {
00280   int i;
00281   SoccerCommand soc;
00282   VecPosition   posAgent = WM->getAgentGlobalPosition();
00283   AngDeg        angBody  = WM->getAgentGlobalBodyAngle();
00284 
00285   // define the top and bottom position of a rectangle in which keeper moves
00286   static const VecPosition posLeftTop( -PITCH_LENGTH/2.0 +
00287                0.7*PENALTY_AREA_LENGTH, -PENALTY_AREA_WIDTH/4.0 );
00288   static const VecPosition posRightTop( -PITCH_LENGTH/2.0 +
00289                0.7*PENALTY_AREA_LENGTH, +PENALTY_AREA_WIDTH/4.0 );
00290 
00291   // define the borders of this rectangle using the two points.
00292   static Line  lineFront = Line::makeLineFromTwoPoints(posLeftTop, posRightTop);
00293   static Line  lineLeft  = Line::makeLineFromTwoPoints(
00294                          VecPosition( -50.0, posLeftTop.getY()), posLeftTop );
00295   static Line  lineRight = Line::makeLineFromTwoPoints(
00296                          VecPosition( -50.0, posRightTop.getY()),posRightTop );
00297 
00298 
00299   if( WM->isBeforeKickOff( ) )
00300   {
00301     if( formations->getFormation() != FT_INITIAL || // not in kick_off formation
00302         posAgent.getDistanceTo( getStrategicPosition() ) > 2.0 )  
00303     {
00304       formations->setFormation( FT_INITIAL );       // go to kick_off formation
00305       ACT->putCommandInQueue( teleportToPos( getStrategicPosition() ) );
00306     }
00307     else                                            // else turn to center
00308     {
00309       ACT->putCommandInQueue( turnBodyToPoint( VecPosition( 0, 0 ), 0 ) );
00310       ACT->putCommandInQueue( alignNeckWithBody( ) );
00311     }
00312     return;
00313   }
00314 
00315   if( WM->getConfidence( OBJECT_BALL ) < PS->getBallConfThr() )
00316   {                                                // confidence ball too  low
00317     ACT->putCommandInQueue( searchBall() );        // search ball
00318     ACT->putCommandInQueue( alignNeckWithBody( ) );
00319   }
00320   else if( WM->getPlayMode() == PM_PLAY_ON || WM->isFreeKickThem() ||
00321            WM->isCornerKickThem() )               
00322   {
00323     if( WM->isBallCatchable() )
00324     {
00325       ACT->putCommandInQueue( soc = catchBall() );
00326       ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00327     }
00328      else if( WM->isBallKickable() )
00329     {
00330        soc = kickTo( VecPosition(0,posAgent.getY()*2.0), 2.0 );    
00331        ACT->putCommandInQueue( soc );
00332        ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00333     }
00334     else if( WM->isInOwnPenaltyArea( getInterceptionPointBall( &i, true ) ) &&
00335              WM->getFastestInSetTo( OBJECT_SET_PLAYERS, OBJECT_BALL, &i ) == 
00336                                                WM->getAgentObjectType() )
00337     {
00338       ACT->putCommandInQueue( soc = intercept( true ) );
00339       ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00340     }
00341     else
00342     {
00343       // make line between own goal and the ball
00344       VecPosition posMyGoal = ( WM->getSide() == SIDE_LEFT )
00345              ? SoccerTypes::getGlobalPositionFlag(OBJECT_GOAL_L, SIDE_LEFT )
00346              : SoccerTypes::getGlobalPositionFlag(OBJECT_GOAL_R, SIDE_RIGHT);
00347       Line lineBall = Line::makeLineFromTwoPoints( WM->getBallPos(), posMyGoal);
00348 
00349       // determine where your front line intersects with the line from ball
00350       VecPosition posIntersect = lineFront.getIntersection( lineBall );
00351 
00352       // outside rectangle, use line at side to get intersection
00353       if (posIntersect.isRightOf( posRightTop ) )
00354         posIntersect = lineRight.getIntersection( lineBall );
00355       else if (posIntersect.isLeftOf( posLeftTop )  )
00356         posIntersect = lineLeft.getIntersection( lineBall );
00357 
00358       if( posIntersect.getX() < -49.0 )
00359         posIntersect.setX( -49.0 );
00360         
00361       // and move to this position
00362       if( posIntersect.getDistanceTo( WM->getAgentGlobalPosition() ) > 0.5 )
00363       {
00364         soc = moveToPos( posIntersect, PS->getPlayerWhenToTurnAngle() );
00365         ACT->putCommandInQueue( soc );
00366         ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00367       }
00368       else
00369       {
00370         ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) );
00371         ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00372       }
00373     }
00374   }
00375   else if( WM->isFreeKickUs() == true || WM->isGoalKickUs() == true )
00376   {
00377     if( WM->isBallKickable() )
00378     {
00379       if( WM->getTimeSinceLastCatch() == 25 && WM->isFreeKickUs() )
00380       {
00381         // move to position with lesser opponents.
00382         if( WM->getNrInSetInCircle( OBJECT_SET_OPPONENTS, 
00383                                           Circle(posRightTop, 15.0 )) <
00384             WM->getNrInSetInCircle( OBJECT_SET_OPPONENTS, 
00385                                            Circle(posLeftTop,  15.0 )) )
00386           soc.makeCommand( CMD_MOVE, posRightTop.getX(),posRightTop.getY(),0.0);
00387         else
00388           soc.makeCommand( CMD_MOVE, posLeftTop.getX(), posLeftTop.getY(), 0.0);
00389         ACT->putCommandInQueue( soc );
00390       }
00391       else if( WM->getTimeSinceLastCatch() > 28 )
00392       {
00393         soc = kickTo( VecPosition(0,posAgent.getY()*2.0), 2.0 );    
00394         ACT->putCommandInQueue( soc );
00395       }
00396       else if( WM->getTimeSinceLastCatch() < 25 )
00397       {
00398         VecPosition posSide( 0.0, posAgent.getY() ); 
00399         if( fabs( (posSide - posAgent).getDirection() - angBody) > 10 )
00400         {
00401           soc = turnBodyToPoint( posSide );
00402           ACT->putCommandInQueue( soc );
00403         }
00404         ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00405       }
00406     }
00407     else if( WM->isGoalKickUs()  )
00408     {
00409       ACT->putCommandInQueue( soc = intercept( true ) );
00410       ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00411     }
00412     else
00413       ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00414   }
00415   else
00416   {
00417      ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) );
00418      ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00419   }
00420 
00421 }
00422 
00434 VecPosition Player::getStrategicPosition( int iPlayer )
00435 {
00436   // -1 is default -> get player number in formation
00437   if( iPlayer == -1 )
00438     iPlayer = formations->getPlayerInFormation();
00439 
00440   // get maximal allowed x coordinate, this is offside x coordinate
00441   double dMaxX = WM->getOffsideX();
00442   
00443   // after standing offside we are not allowed to move for ball
00444   // with a goal kick of them we are not allowed to move into penalty area
00445   if( WM->isOffsideUs( ) )
00446     dMaxX = min( dMaxX, WM->getBallPos().getX() - 1.0 );
00447   if( WM->isGoalKickThem() );
00448     dMaxX = min( dMaxX, PENALTY_X - 1.0 );
00449 
00450 
00451   if( WM->getConfidence( OBJECT_BALL ) > PS->getBallConfThr() )
00452     return formations->getStrategicPosition( iPlayer, WM->getBallPos(), dMaxX );
00453   else
00454     return formations->getStrategicPosition( iPlayer, VecPosition(0,0), dMaxX );
00455 }
00456 
00468 void Player::handleStdin( )
00469 {
00470   char buf[MAX_MSG];
00471 
00472   while( bContLoop )
00473   {
00474     fgets( buf, MAX_MSG, stdin ); 
00475     executeStringCommand( buf );
00476   }
00477 }
00478 
00484 void Player::showStringCommands( ostream& out )
00485 {
00486   out << "Basic commands:"                                << endl <<
00487          " a(ctions)"                                     << endl <<
00488          " c(atch) direction"                             << endl <<
00489          " cs(lientsettings"                              << endl <<
00490          " d(ash) power [ times ]"                        << endl <<
00491          " g(oto) x y"                                    << endl <<
00492          " h(elp)"                                        << endl <<
00493          " i(ntercept) x y"                               << endl <<
00494          " k(ick) power angle"                            << endl <<
00495          " ka x y endspeed "                              << endl <<
00496          " m(ove) x y"                                    << endl <<
00497          " n(eck) angle"                                  << endl <<
00498          " o(pponents in cone) width dist"                << endl <<
00499          " p(redict cycles to) x y"                       << endl <<
00500          " q(uit)"                                        << endl <<
00501          " s(ay) message"                                 << endl <<
00502          " ss(erversettings)"                             << endl <<
00503          " t(urn) angle"                                  << endl <<
00504          " v(iewmode) narrow | normal | wide low | high"  << endl <<
00505          " w(orldmodel)"                                  << endl;
00506 }
00507 
00512 bool Player::executeStringCommand( char *str)
00513 {
00514   SoccerCommand socCommand;
00515   int           i;
00516   double        x, y;
00517 
00518   switch( str[0] )
00519   {
00520     case 'a':                                  // actions
00521       WM->showQueuedCommands();
00522       break;
00523     case 'c':                                 // catch dir or ps
00524       if( strlen(str) > 1 && str[1] == 's' )
00525       {
00526         PS->show( cout, ":" );
00527         break;
00528       }
00529       socCommand.makeCommand( CMD_CATCH, Parse::parseFirstInt( &str ) );
00530       break;
00531     case 'd':                                 // dash
00532       socCommand.commandType = CMD_DASH;
00533       socCommand.dPower      = Parse::parseFirstDouble( &str );
00534       socCommand.iTimes      = Parse::parseFirstInt   ( &str );
00535       if( socCommand.iTimes == 0 ) socCommand.iTimes = 1;
00536       break;
00537     case 'h':                                // help
00538       showStringCommands( cout );
00539       return true;
00540     case 'k':                                // kick or ka (kick advanced)
00541       socCommand.commandType = CMD_KICK;
00542       if( str[1] == 'a' ) // advanced kick
00543       {
00544         double x = Parse::parseFirstDouble( &str );
00545         double y = Parse::parseFirstDouble( &str );
00546         double e = Parse::parseFirstDouble( &str );
00547         socCommand = kickTo( VecPosition( x, y), e );
00548       }
00549       else
00550       {
00551         socCommand.dPower = Parse::parseFirstDouble( &str );
00552         socCommand.dAngle = Parse::parseFirstDouble( &str );
00553       }
00554       break;
00555     case 'm':                               // move
00556       socCommand.commandType = CMD_MOVE;
00557       socCommand.dX          = Parse::parseFirstDouble( &str );
00558       socCommand.dY          = Parse::parseFirstDouble( &str );
00559       socCommand.dAngle      = Parse::parseFirstDouble( &str );
00560       break;
00561     case 'n':                              // turn_neck
00562       socCommand.commandType = CMD_TURNNECK;
00563       socCommand.dAngle      = Parse::parseFirstDouble( &str );
00564       break;
00565     case 'o':                              // count nr opp in cone
00566       x = Parse::parseFirstDouble( &str );
00567       y = Parse::parseFirstDouble( &str );
00568       i = WM->getNrInSetInCone( OBJECT_SET_OPPONENTS, x, 
00569               WM->getAgentGlobalPosition(),
00570               WM->getAgentGlobalPosition()+VecPosition( y,
00571           WM->getAgentGlobalNeckAngle(), POLAR ) );
00572       printf( "%d opponents\n", i );
00573       return true;
00574     case 'p':                              // predict cycles to point
00575       x = Parse::parseFirstDouble( &str );
00576       y = Parse::parseFirstDouble( &str );
00577       i = WM->predictNrCyclesToPoint( WM->getAgentObjectType(),
00578                      VecPosition( x, y ), PS->getPlayerWhenToTurnAngle() );
00579       printf( "%d cycles\n", i );
00580       return true;
00581     case 'q':                             // quit
00582       bContLoop = false;
00583       return true;
00584     case 's':                             // ss (serversettings) or say
00585       if( strlen(str) > 1 && str[1] == 's' )
00586       {
00587         SS->show( cout, ":" );
00588         break;
00589       }
00590       socCommand.commandType = CMD_SAY;
00591       Parse::gotoFirstOccurenceOf( ' ', &str );
00592       Parse::gotoFirstNonSpace( &str );
00593       strcpy( socCommand.str, str);
00594       break;
00595     case 't':                             // turn
00596       socCommand.commandType = CMD_TURN;
00597       socCommand.dAngle      = Parse::parseFirstDouble( &str );
00598       break;
00599     case 'v':                             // change_view
00600       socCommand.commandType = CMD_CHANGEVIEW;
00601       Parse::gotoFirstOccurenceOf(' ', &str );
00602       Parse::gotoFirstNonSpace( &str );
00603       socCommand.va          = SoccerTypes::getViewAngleFromStr( str );
00604       Parse::gotoFirstOccurenceOf(' ', &str );
00605       Parse::gotoFirstNonSpace( &str );
00606       socCommand.vq          = SoccerTypes::getViewQualityFromStr( str );
00607       break;
00608     case 'w':                            // worldmodel
00609       WM->show();
00610       return true;
00611     default:                             // default: send entered string
00612       ACT->sendMessage( str );
00613       return true;
00614   }
00615   if( socCommand.commandType != CMD_ILLEGAL ) // when socCommand is set
00616     ACT->putCommandInQueue( socCommand );     // send it.
00617 
00618   return true;
00619 }
00620 
00630 void* stdin_callback( void * v )
00631 {
00632   Log.log( 1, "Starting to listen for user input" );
00633   Player* p = (Player*)v;
00634   p->handleStdin();
00635   return NULL;
00636 }
00637 
00638 
00639 
00640 /********************** SAY **************************************************/
00641 
00650 bool Player::shallISaySomething( )
00651 {
00652   bool        bReturn;
00653 
00654   bReturn  = ((WM->getCurrentCycle() - m_lastSay) >= SS->getHearDecay());
00655   bReturn  &= amIAgentToSaySomething();
00656 
00657   return bReturn;
00658 }
00659 
00665 bool Player::amIAgentToSaySomething()
00666 {
00667   VecPosition posBall  = WM->getBallPos();
00668   bool bReturn = false;
00669   if( posBall.getX() > PITCH_LENGTH/6.0 )
00670   {
00671     if( posBall.getY() > 0 && WM->getPlayerNumber() == 7  )
00672       bReturn = true;
00673     else if( posBall.getY() < 0 && WM->getPlayerNumber() == 8  )
00674       bReturn = true;
00675   }
00676   else if( fabs( posBall.getX() ) < -PITCH_LENGTH/6.0 )
00677   {
00678     if( posBall.getY() > 0 && WM->getPlayerNumber() == 8 )
00679       bReturn = true;
00680     else if( posBall.getY() < 0 && WM->getPlayerNumber() == 7 )
00681        bReturn = true;
00682   }
00683   else
00684   {
00685     if( posBall.getY() > 0 && WM->getPlayerNumber() == 8 )
00686       bReturn = true;
00687     else if( posBall.getY() < 0 && WM->getPlayerNumber() == 7 )
00688       bReturn = true;
00689   }
00690   return bReturn;
00691 }
00692 
00707 SoccerCommand Player::sayWorldStatus( )
00708 {
00709   char    strMsg[MAX_SAY_MSG];
00710   char    tmp[MAX_SAY_MSG];
00711   char    *format = "%d %2.1f %2.1f %1.2f ";
00712   char    *formatg = "%dg %2.1f %2.1f %1.2f ";
00713   int     i = WM->getCurrentCycle();
00714   int     iLength = 0;
00715   double  dConf;
00716   ObjectT obj;
00717 
00718   // encode message by adding characters of 'side' + 'acegi' to each digit of
00719   // cycle number and own player number. So cycle 0453 and player 10 will become
00720   // 'lagjjs' for the left team. decoding is easy, by subtracting 'acegi' and
00721   // converting difference to integers.
00722   iLength += sprintf( strMsg, "%c%c%c%c%c%c ",
00723       (WM->getSide() == SIDE_LEFT) ? 'l' : 'r', (i/1000)%10+'a', (i/100)%10+'c',
00724       (i/10)%10+'e', (i/1)%10+'g', WM->getPlayerNumber()+'i' );
00725 
00726   // add agent global position and velocity
00727   VecPosition pos   = WM->getAgentGlobalPosition();
00728   VecPosition vel   = WM->getAgentGlobalVelocity();
00729   iLength += sprintf(tmp,"%2.1f %2.1f %1.2f %1.2f ",
00730                pos.getX(), pos.getY(), vel.getX(), vel.getY()) ;
00731   strcat( strMsg, tmp );
00732 
00733   // add ball global position, velocity and confidence
00734   pos   = WM->getBallPos();
00735   vel   = WM->getGlobalVelocity( OBJECT_BALL );
00736   dConf = WM->getConfidence( OBJECT_BALL );
00737   if( dConf > PS->getBallConfThr() )
00738     iLength += sprintf(tmp, "%2.1f %2.1f %1.2f %1.2f %1.2f ",
00739         pos.getX(), pos.getY(), vel.getX(),vel.getY(), dConf);
00740   else
00741     iLength += sprintf( tmp, "%s", "" );
00742   strcat( strMsg, "(" );
00743   strcat( strMsg, tmp );
00744   strcat( strMsg, ")" );
00745 
00746   // add perfect teammate information
00747   strcat( strMsg, "(" );
00748   for( i = 0 ; i < MAX_TEAMMATES; i ++ )
00749   {
00750     obj   = (ObjectT)((int)OBJECT_TEAMMATE_1+i);
00751     if( WM->isConfidenceGood( obj ) && WM->isKnownPlayer(obj) )
00752     {
00753       pos   = WM->getGlobalPosition( obj );
00754       vel   = WM->getGlobalVelocity     ( obj );
00755       dConf = WM->getConfidence      ( obj );
00756       iLength += sprintf(tmp, format, i+1,pos.getX(), pos.getY(), dConf);
00757       strcat( strMsg, tmp );
00758     }
00759   }
00760 
00761   // add unsure teammate information
00762   for( i = 0 ; i < MAX_TEAMMATES; i ++ )
00763   {
00764     obj   = (ObjectT)((int)OBJECT_TEAMMATE_1+i);
00765 
00766     if( WM->isConfidenceGood( obj ) && !WM->isKnownPlayer( obj ) )
00767     {
00768       pos   = WM->getGlobalPosition( obj );
00769       vel   = WM->getGlobalVelocity     ( obj );
00770       dConf = WM->getConfidence      ( obj );
00771       iLength += sprintf(tmp, format, -1, pos.getX(), pos.getY(), dConf);
00772       strcat( strMsg, tmp );
00773     }
00774   }
00775 
00776   strcat( strMsg, ")" );
00777 
00778   // add perfect opponent information (opponent number known) if enough space
00779   strcat( strMsg, "(" );
00780   for( i = 0 ; i < MAX_OPPONENTS; i ++ )
00781   {
00782     obj   = (ObjectT)((int)OBJECT_OPPONENT_1+i);
00783     if( WM->isConfidenceGood( obj ) && WM->isKnownPlayer(obj) && 
00784         iLength < MAX_SAY_MSG-30) // 30 is length of one opponent info
00785     {
00786       pos   = WM->getGlobalPosition( obj );
00787       vel   = WM->getGlobalVelocity     ( obj );
00788       dConf = WM->getConfidence      ( obj );
00789       if( WM->getOppGoalieType() == obj )
00790         iLength += sprintf(tmp,formatg,i+1,pos.getX(),pos.getY(), dConf);
00791       else
00792         iLength += sprintf(tmp, format, i+1,pos.getX(), pos.getY(), dConf);
00793       strcat( strMsg, tmp );
00794     }
00795   }
00796 
00797   // add unsure opponent information (opponent number unknown)
00798   for( i = 0 ; i < MAX_OPPONENTS; i ++ )
00799   {
00800     obj   = (ObjectT)((int)OBJECT_OPPONENT_1+i);
00801     if( WM->isConfidenceGood( obj ) && 
00802         !WM->isKnownPlayer(obj) && 
00803         iLength < MAX_SAY_MSG-30)          // 30 is length of one opponent info
00804     {
00805       pos   = WM->getGlobalPosition( obj );
00806       vel   = WM->getGlobalVelocity     ( obj );
00807       dConf = WM->getConfidence      ( obj );
00808       iLength += sprintf(tmp, format, -1,pos.getX(), pos.getY(), dConf);
00809       strcat( strMsg, tmp );
00810     }
00811   }
00812   strcat( strMsg, ")" );
00813 
00814   return SoccerCommand( CMD_SAY, strMsg );
00815 }
00816 
00821 void Player::test_only_update()
00822 {
00823   while( bContLoop )
00824   {
00825     WM->updateAll();
00826     if(  WM->waitForNewInformation() == false )
00827     {
00828         printf("Server dead; exiting" );
00829         bContLoop =  false;
00830     }
00831   }
00832 }

Generated on Thu Mar 7 00:37:43 2002 for UvA Trilearn 2001 by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001