src/Player.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000-2003, 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 */
00030 
00049 #include "Player.h"
00050 #include "Parse.h"
00051 
00052 #ifndef WIN32
00053   #include <sys/poll.h> // needed for 'poll'
00054 #endif
00055 #include <stdio.h>
00056 #include <stdlib.h>
00057 #include <time.h> 
00058 
00059 extern Logger LogDraw;
00060 
00070 Player::Player( ActHandler* act, WorldModel *wm, ServerSettings *ss,
00071       PlayerSettings *ps,
00072       Formations *fs, char* strTeamName, double dVersion, int iReconnect )
00073 
00074 {
00075   log = new SituationsLog(fs->getPlayerInFormation(), strTeamName);
00076   
00077   char str[MAX_MSG];
00078 
00079   ACT           = act;
00080   WM            = wm;
00081   SS            = ss;
00082   PS            = ps;
00083   formations    = fs;
00084   bContLoop     = true;
00085   m_iPenaltyNr  = -1;
00086   WM->setTeamName( strTeamName );
00087   m_timeLastSay = -5;
00088   m_objMarkOpp  = OBJECT_ILLEGAL;
00089   m_actionPrev  = ACT_ILLEGAL;
00090   
00091   goalMiddle.setVecPosition(PITCH_LENGTH/2, 0, CARTESIAN);
00092 
00093   // wait longer as role number increases, to make sure players appear at the
00094   // field in the correct order
00095 #ifdef WIN32
00096   Sleep( formations->getPlayerInFormation()*500 );
00097 #else
00098   poll( 0, 0, formations->getPlayerInFormation()*500 );
00099 #endif
00100 
00101   // create initialisation string
00102   if( iReconnect != -1 )
00103     sprintf( str, "(reconnect %s %d)", strTeamName, iReconnect );
00104   else if( formations->getPlayerType() == PT_GOALKEEPER )
00105     sprintf( str, "(init %s (version %f) (goalie))", strTeamName, dVersion );
00106   else
00107     sprintf( str, "(init %s (version %f))", strTeamName, dVersion );
00108   ACT->sendMessage( str );
00109   
00110 }
00111 
00112 Player::~Player(){
00113   delete log;
00114 }
00115 
00120 void Player::mainLoop( )
00121 {
00122   char str[MAX_MSG];
00123   Timing timer;
00124 
00125   // wait for new information from the server
00126   // cannot say bContLoop=WM->wait... since bContLoop can be changed elsewhere
00127   if(  WM->waitForNewInformation() == false )
00128     bContLoop =  false;
00129 
00130   // and set the clang version
00131   sprintf( str, "(clang (ver 8 8))" );
00132   ACT->sendMessage( str );
00133 
00134   while( bContLoop )                                 // as long as server alive
00135   {
00136     Log.logWithTime( 3, "  start update_all" );
00137 //    Log.setHeader( WM->getCurrentCycle(), WM->getPlayerNumber() );
00138     Log.setHeader( WM->getCurrentCycle() );
00139     LogDraw.setHeader( WM->getCurrentCycle() );
00140 
00141     if( WM->updateAll( ) == true )
00142     {
00143       timer.restartTime();
00144       SoccerCommand soc;
00145       if( ( WM->isPenaltyUs( ) || WM->isPenaltyThem() ) )
00146         performPenalty();
00147       else if( WM->getPlayMode() == PM_FROZEN )
00148         ACT->putCommandInQueue( turnBodyToObject( OBJECT_BALL )  ); 
00149       else
00150       {
00151         switch( formations->getPlayerType( ) )        // determine right loop
00152         {
00153           case PT_GOALKEEPER:       soc = goalieMainLoop( );     break;
00154           case PT_DEFENDER_SWEEPER:
00155           case PT_DEFENDER_CENTRAL:
00156           case PT_DEFENDER_WING:    soc = defenderMainLoop( );   break;
00157           case PT_MIDFIELDER_CENTER:
00158           case PT_MIDFIELDER_WING:  soc = midfielderMainLoop( ); break;
00159           case PT_ATTACKER:
00160           case PT_ATTACKER_WING:    soc = attackerMainLoop( );   break;
00161           case PT_ILLEGAL:
00162           default: break;
00163         }
00164 
00165         if( shallISaySomething(soc) == true )           // shall I communicate
00166         {
00167           m_timeLastSay = WM->getCurrentTime();
00168           char strMsg[MAX_SAY_MSG];
00169           if( WM->getPlayerNumber() == 6 &&
00170               WM->getBallPos().getX() < - PENALTY_X + 4.0  )
00171             sayOppAttackerStatus( strMsg );
00172           else
00173             sayBallStatus( strMsg );
00174           if( strlen( strMsg ) != 0 )
00175             Log.log( 600, "send communication string: %s", strMsg );
00176           WM->setCommunicationString( strMsg );
00177         }
00178       }
00179       Log.logWithTime( 3, "  determined action; waiting for new info" );
00180       // directly after see message, will nog get better info, so send commands
00181       if( WM->getTimeLastSeeMessage() == WM->getCurrentTime() ||
00182           (SS->getSynchMode() == true && WM->getRecvThink() == true ))
00183       {
00184         Log.logWithTime( 3, "  send messages directly" );
00185         ACT->sendCommands( );
00186         Log.logWithTime( 3, "  sent messages directly" );
00187         if( SS->getSynchMode() == true  )
00188         {
00189           WM->processRecvThink( false );
00190           ACT->sendMessageDirect( "(done)" );
00191         }
00192       }
00193 
00194     }
00195     else
00196       Log.logWithTime( 3, "  HOLE no action determined; waiting for new info");
00197 
00198     if( WM->getCurrentCycle()%(SS->getHalfTime()*SS->getSimulatorStep()) != 0 )
00199     {
00200       if( LogDraw.isInLogLevel( 600 ) )
00201       {
00202         WM->logDrawInfo( 600 );
00203       }
00204 
00205       if( LogDraw.isInLogLevel( 601 ) )
00206         WM->logDrawBallInfo( 601 );
00207 
00208       if( LogDraw.isInLogLevel( 700 ) )
00209         WM->logCoordInfo( 700 );
00210     }
00211  
00212     Log.logWithTime( 604, "time for action: %f", timer.getElapsedTime()*1000 );
00213            
00214     // wait for new information from the server cannot say
00215     // bContLoop=WM->wait... since bContLoop can be changed elsewhere
00216     if(  WM->waitForNewInformation() == false )
00217         bContLoop =  false;
00218   }
00219 
00220   // shutdow, print hole and number of players seen statistics
00221   printf("Shutting down player %d\n", WM->getPlayerNumber() );
00222   printf("   Number of holes: %d (%f)\n", WM->iNrHoles,
00223                          ((double)WM->iNrHoles/WM->getCurrentCycle())*100 );
00224   printf("   Teammates seen: %d (%f)\n", WM->iNrTeammatesSeen,
00225                          ((double)WM->iNrTeammatesSeen/WM->getCurrentCycle()));
00226   printf("   Opponents seen: %d (%f)\n", WM->iNrOpponentsSeen,
00227                          ((double)WM->iNrOpponentsSeen/WM->getCurrentCycle()));
00228 
00229 }
00230 
00231 
00233 SoccerCommand Player::goalieMainLoop( )
00234 {
00235   return deMeer5_goalie();
00236 }
00237 
00239 SoccerCommand Player::defenderMainLoop( )
00240 {
00241   return deMeer5() ;
00242 }
00243 
00245 SoccerCommand Player::midfielderMainLoop( )
00246 {
00247   return deMeer5() ;
00248 }
00249 
00251 SoccerCommand Player::attackerMainLoop( )
00252 {
00253   return deMeer5() ;
00254 }
00255 
00260 VecPosition Player::getDeadBallPosition(  )
00261 {
00262   VecPosition pos, posBall = WM->getBallPos();
00263   VecPosition posAgent = WM->getAgentGlobalPosition();
00264   double dDist;
00265 
00266   // determine point to move to
00267   if( WM->isKickInUs()  )
00268     pos = posBall + VecPosition( -1.5, sign( posBall.getY() )*1.5 );
00269   else if( WM->isCornerKickUs( ) )
00270     pos = posBall + VecPosition( 1.5, sign( posBall.getY() ) * 1.5 );
00271   else if( WM->isFreeKickUs() || WM->isOffsideThem() || WM->isGoalKickUs() ||
00272            WM->isFreeKickFaultThem() || WM->isBackPassThem() )
00273     pos = posBall + VecPosition( -1.5, 0.0 );
00274   else
00275     return VecPosition( UnknownDoubleValue, UnknownDoubleValue );
00276 
00277   AngDeg      angBall = (posBall-posAgent).getDirection() ;
00278   ObjectT     obj = WM->getClosestInSetTo( OBJECT_SET_PLAYERS,
00279                                            WM->getAgentObjectType(), &dDist);
00280   VecPosition posPlayer = WM->getGlobalPosition( obj );
00281 
00282   // change point when heading towards other player or towards the ball
00283   if( fabs( angBall - (posPlayer-posAgent).getDirection() ) < 20 &&
00284       dDist < 6 )
00285     pos -= VecPosition( 5, 0 );
00286   if( fabs( angBall -  (pos-posAgent).getDirection()) < 20 )
00287   {
00288     angBall = VecPosition::normalizeAngle( angBall - 90 );
00289     pos = posBall + VecPosition( 1, angBall , POLAR );
00290   }
00291   return pos;
00292 }
00293 
00305 void Player::handleStdin( )
00306 {
00307   char buf[MAX_MSG];
00308 
00309   while( bContLoop )
00310   {
00311 #ifdef WIN32
00312     cin.getline( buf, MAX_MSG );
00313 #else
00314     fgets( buf, MAX_MSG, stdin ); // does unblock with signal !!!!!
00315 #endif
00316    printf( "after fgets: %s\n", buf );
00317    executeStringCommand( buf );
00318   }
00319 }
00320 
00326 void Player::showStringCommands( ostream& out )
00327 {
00328   out << "Basic commands:"                                << endl <<
00329          " a(ctions)"                                     << endl <<
00330          " c(atch) direction"                             << endl <<
00331          " cs(lientsettings"                              << endl <<
00332          " d(ash) power [ times ]"                        << endl <<
00333          " de(bug) nr_cycles"                             << endl <<
00334          " g(oto) x y"                                    << endl <<
00335          " h(elp)"                                        << endl <<
00336          " i(ntercept) x y"                               << endl <<
00337          " k(ick) power angle"                            << endl <<
00338          " ka x y endspeed "                              << endl <<
00339          " m(ove) x y"                                    << endl <<
00340          " n(eck) angle"                                  << endl <<
00341          " o(pponents in cone) width dist"                << endl <<
00342          " p(redict cycles to) x y"                       << endl <<
00343          " q(uit)"                                        << endl <<
00344          " s(ay) message"                                 << endl <<
00345          " ss(erversettings)"                             << endl <<
00346          " t(urn) angle"                                  << endl <<
00347          " v(iewmode) narrow | normal | wide low | high"  << endl <<
00348          " w(orldmodel)"                                  << endl;
00349 }
00350 
00355 bool Player::executeStringCommand( char *str)
00356 {
00357   SoccerCommand socCommand;
00358   int           i;
00359   double        x, y;
00360 
00361   switch( str[0] )
00362   {
00363     case 'a':                                 // actions
00364       WM->showQueuedCommands();
00365       break;
00366     case 'c':                                 // catch dir or cs
00367       if( strlen(str) > 1 && str[1] == 's' )
00368       {
00369         PS->show( cout, ":" );
00370         break;
00371       }
00372       socCommand.makeCommand( CMD_CATCH, Parse::parseFirstInt( &str ) );
00373       break;
00374     case 'd':                                 // dash
00375       socCommand.commandType = CMD_DASH;
00376       socCommand.dPower      = Parse::parseFirstDouble( &str );
00377       socCommand.iTimes      = Parse::parseFirstInt   ( &str );
00378       if( socCommand.iTimes == 0 ) socCommand.iTimes = 1;
00379       break;
00380     case 'h':                                // help
00381       showStringCommands( cout );
00382       return true;
00383     case 'k':                                // kick or ka (kick advanced)
00384       socCommand.commandType = CMD_KICK;
00385       if( str[1] == 'a' ) // advanced kick
00386       {
00387         double x = Parse::parseFirstDouble( &str );
00388         double y = Parse::parseFirstDouble( &str );
00389         double e = Parse::parseFirstDouble( &str );
00390         socCommand = kickTo( VecPosition( x, y), e );
00391       }
00392       else
00393       {
00394         socCommand.dPower = Parse::parseFirstDouble( &str );
00395         socCommand.dAngle = Parse::parseFirstDouble( &str );
00396       }
00397       break;
00398     case 'm':                               // move
00399       socCommand.commandType = CMD_MOVE;
00400       socCommand.dX          = Parse::parseFirstDouble( &str );
00401       socCommand.dY          = Parse::parseFirstDouble( &str );
00402       socCommand.dAngle      = Parse::parseFirstDouble( &str );
00403       break;
00404     case 'n':                              // turn_neck
00405       socCommand.commandType = CMD_TURNNECK;
00406       socCommand.dAngle      = Parse::parseFirstDouble( &str );
00407       break;
00408     case 'o':                              // count nr opp in cone
00409       x = Parse::parseFirstDouble( &str );
00410       y = Parse::parseFirstDouble( &str );
00411       i = WM->getNrInSetInCone( OBJECT_SET_OPPONENTS, x, 
00412                                 WM->getAgentGlobalPosition(),
00413                                 WM->getAgentGlobalPosition() + 
00414                                 VecPosition( y,
00415                                              WM->getAgentGlobalNeckAngle(), 
00416                                              POLAR ) );
00417       printf( "%d opponents\n", i );
00418       return true;
00419     case 'p':                              // predict cycles to point
00420       x = Parse::parseFirstDouble( &str );
00421       y = Parse::parseFirstDouble( &str );
00422       i = WM->predictNrCyclesToPoint( WM->getAgentObjectType(),
00423                                       VecPosition( x, y ) );
00424       printf( "%d cycles\n", i );
00425       return true;
00426     case 'q':                             // quit
00427       bContLoop = false;
00428       return true;
00429     case 's':                             // ss (serversettings) or say
00430       if( strlen(str) > 1 && str[1] == 's' )
00431       {
00432         SS->show( cout, ":" );
00433         break;
00434       }
00435       socCommand.commandType = CMD_SAY;
00436       Parse::gotoFirstOccurenceOf( ' ', &str );
00437       Parse::gotoFirstNonSpace( &str );
00438       strcpy( socCommand.str, str);
00439       break;
00440     case 't':                             // turn
00441       socCommand.commandType = CMD_TURN;
00442       socCommand.dAngle      = Parse::parseFirstDouble( &str );
00443       break;
00444     case 'v':                             // change_view
00445       socCommand.commandType = CMD_CHANGEVIEW;
00446       Parse::gotoFirstOccurenceOf(' ', &str );
00447       Parse::gotoFirstNonSpace( &str );
00448       socCommand.va          = SoccerTypes::getViewAngleFromStr( str );
00449       Parse::gotoFirstOccurenceOf(' ', &str );
00450       Parse::gotoFirstNonSpace( &str );
00451       socCommand.vq          = SoccerTypes::getViewQualityFromStr( str );
00452       break;
00453     case 'w':                            // worldmodel
00454       WM->show();
00455       return true;
00456     default:                             // default: send entered string
00457       ACT->sendMessage( str );
00458       return true;
00459   }
00460   if( socCommand.commandType != CMD_ILLEGAL ) // when socCommand is set
00461     ACT->putCommandInQueue( socCommand );     // send it.
00462 
00463   return true;
00464 }
00465 
00475 #ifdef WIN32
00476 DWORD WINAPI stdin_callback( LPVOID v )
00477 #else
00478 void* stdin_callback( void * v )
00479 #endif
00480 
00481 {
00482   Log.log( 1, "Starting to listen for user input" );
00483   Player* p = (Player*)v;
00484   p->handleStdin();
00485   return 0;
00486 }
00487 
00488 /********************** SAY **************************************************/
00489 
00492 bool Player::shallISaySomething( SoccerCommand socPri )
00493 {
00494   bool        bReturn;
00495 
00496   bReturn  = ((WM->getCurrentTime() - m_timeLastSay) >= SS->getHearDecay());
00497   bReturn  &= amIAgentToSaySomething( socPri );
00498   bReturn  &= (WM->getCurrentCycle() > 0 );
00499 
00500   return bReturn;
00501 }
00502 
00506 bool Player::amIAgentToSaySomething( SoccerCommand socPri )
00507 {
00508   double  dDist;
00509   ObjectT obj;
00510 
00511   // get the closest teammate to the ball, if we are not him, we do not
00512   // communicate since he will
00513   obj = WM->getClosestInSetTo( OBJECT_SET_TEAMMATES,OBJECT_BALL,&dDist);
00514   if( dDist < SS->getVisibleDistance() &&
00515       obj != WM->getAgentObjectType() )
00516     return false;
00517 
00518   // in the defense, player 6 keeps track of the opponent attacker
00519   if( WM->getBallPos().getX() < - PENALTY_X + 4.0 &&
00520       WM->getConfidence( OBJECT_BALL ) > 0.96 &&
00521       WM->getPlayerNumber() == 6 &&
00522       WM->getCurrentCycle() % 3 == 0 ) // once very 3 cycles is enough
00523   {
00524     Log.log( 600, "player 6 is going to communicate attacker info" );
00525     return true;
00526   }
00527 
00528   VecPosition posBallPred;
00529   WM->predictBallInfoAfterCommand( socPri, &posBallPred );
00530   VecPosition posAgentPred = WM->predictAgentPosAfterCommand( socPri );
00531   // in all other cases inform teammates of ball when you have good information
00532   if( ( WM->getTimeChangeInformation(OBJECT_BALL) == WM->getCurrentTime() &&
00533           WM->getRelativeDistance( OBJECT_BALL ) < 20.0 &&
00534           WM->getTimeLastSeen( OBJECT_BALL ) == WM->getCurrentTime() )
00535         ||
00536       (
00537        WM->getRelativeDistance( OBJECT_BALL ) < SS->getVisibleDistance() &&
00538        WM->getTimeLastSeen( OBJECT_BALL ) == WM->getCurrentTime()  
00539        )
00540       ||
00541       ( // pass ball
00542        WM->getRelativeDistance( OBJECT_BALL ) < SS->getMaximalKickDist() &&
00543        posBallPred.getDistanceTo( posAgentPred ) > SS->getMaximalKickDist() 
00544        )
00545       )
00546     return true;
00547 
00548   return false;
00549 }
00550 
00553 void Player::sayOppAttackerStatus( char* strMsg )
00554 {
00555   char    strTmp[MAX_SAY_MSG];
00556 
00557   // fill the first byte with some encoding to indicate the current cycle.
00558   // The second byte   is the last digit of the cycle added to 'a'.
00559   sprintf( strMsg, "%c", 'a' + WM->getCurrentCycle()%10   );
00560 
00561   // fill the second byte with information about the offside line.
00562   // Enter either a value between a-z or A-Z indicating. This gives 52 possible
00563   // values which correspond with meters on the field. So B means the offside
00564   // line lies at 27.0.
00565   int iOffside = (int)WM->getOffsideX();
00566   if( iOffside < 26 ) // 0..25
00567     sprintf( strTmp, "%c", 'a' + iOffside );
00568   else               // 26...
00569     sprintf( strTmp, "%c", 'A' + max(iOffside - 26, 25) );
00570   strcat( strMsg, strTmp );
00571 
00572   // find the closest opponent attacker to the penalty spot.
00573   double dDist ;
00574   ObjectT objOpp = WM->getClosestInSetTo( OBJECT_SET_OPPONENTS,
00575          VecPosition(- PITCH_LENGTH/2.0 + 11.0, 0 ), &dDist  ) ;
00576 
00577   if( objOpp == OBJECT_ILLEGAL || dDist >= 20.0 )
00578   {
00579     strncpy( strMsg, "", 0 );
00580     return;
00581   }
00582 
00583   VecPosition posOpp = WM->getGlobalPosition( objOpp );
00584   if( fabs( posOpp.getY() ) > 10 )
00585   {
00586     strncpy( strMsg, "", 0 );
00587     return;
00588   }
00589 
00590   // encode the position of this attacker in the visual message. The
00591   // player_number is the third byte, then comes the x position in 3 digits (it
00592   // is assumed this value is always negative), a space and finally the y
00593   // position in 2 digits. An example of opponent nr. 9 at position
00594   // (-40.3223,-3.332) is "j403 -33)
00595   sprintf( strTmp, "%c%d %d", 'a' + SoccerTypes::getIndex( objOpp ) ,
00596                               (int)(fabs(posOpp.getX())*10),
00597                               (int)(posOpp.getY()*10));
00598   strcat( strMsg, strTmp );
00599 
00600   return ;
00601 }
00602 
00607 void Player::sayBallStatus( char * strMsg  )
00608 {
00609   VecPosition posBall = WM->getGlobalPosition( OBJECT_BALL );
00610   VecPosition velBall = WM->getGlobalVelocity( OBJECT_BALL );
00611   int iDiff = 0;
00612   SoccerCommand soc = ACT->getPrimaryCommand();
00613 
00614   if( WM->getRelativeDistance( OBJECT_BALL ) < SS->getMaximalKickDist() )
00615   {
00616     // if kick and a pass
00617     if( soc.commandType == CMD_KICK )
00618     {
00619       WM->predictBallInfoAfterCommand( soc, &posBall, &velBall );
00620       VecPosition posAgent = WM->predictAgentPos( 1, 0 );
00621       if( posBall.getDistanceTo( posAgent ) > SS->getMaximalKickDist() + 0.2 )
00622         iDiff = 1;
00623     }
00624 
00625     if( iDiff == 0 )
00626     {
00627       posBall = WM->getGlobalPosition( OBJECT_BALL );
00628       velBall.setVecPosition( 0, 0 );
00629     }
00630   }
00631   Log.log( 600, "create comm. ball after: (%1.2f,%1.2f)(%1.2f,%1.2f) diff %d",
00632      posBall.getX(), posBall.getY(), velBall.getX(), velBall.getY(), iDiff);
00633   makeBallInfo( posBall, velBall, iDiff, strMsg );
00634 }
00635 
00643 void Player::makeBallInfo( VecPosition posBall, VecPosition velBall, int iDiff,
00644                             char * strMsg  )
00645 {
00646   char    strTmp[MAX_SAY_MSG];
00647 
00648   // fill the first byte with some encoding to indicate the next cycle.
00649   // The second byte is the last digit of the cycle added to 'a'.
00650   sprintf( strMsg, "%c", 'a' + (WM->getCurrentCycle()+iDiff)%10   );
00651 
00652   // fill the second byte with information about the offside line.
00653   // Enter either a value between a-z or A-Z indicating. This gives 52 possible
00654   // values which correspond with meters on the field. So B means the offside
00655   // line lies at 27.0.
00656   int iOffside = (int)( WM->getOffsideX( false ) - 1.0 );
00657   if( iOffside < 26 ) // 0..25
00658     sprintf( strTmp, "%c", 'a' + max( 0, iOffside) );
00659   else               // 26...
00660     sprintf( strTmp, "%c", 'A' + min(iOffside - 26, 25) );
00661   strcat( strMsg, strTmp );
00662 
00663   // First add al values to a positive interval, since then we don't need
00664   // another byte for the minus sign. then take one digit at a time
00665   double x = max(0,min( rint( posBall.getX() + 48.0), 99.0));
00666   sprintf( strTmp, "%c%c%c%c%c%c%c%c",
00667      '0' + ((int)( x                          ) % 100 ) / 10 ,
00668      '0' + ((int)( x                          ) % 100 ) % 10 ,
00669      '0' + ((int)( rint(posBall.getY() + 34.0)) % 100 ) / 10 ,
00670      '0' + ((int)( rint(posBall.getY() + 34.0)) % 100 ) % 10 ,
00671      '0' + ((int)(( velBall.getX() + 2.7) * 10 )) / 10 ,
00672      '0' + ((int)(( velBall.getX() + 2.7) * 10 )) % 10 ,
00673      '0' + ((int)(( velBall.getY() + 2.7) * 10 )) / 10 ,
00674      '0' + ((int)(( velBall.getY() + 2.7) * 10 )) % 10 );
00675   strcat( strMsg, strTmp );
00676   Log.log( 6560, "say (%d) %s\n", WM->getPlayerNumber() , strMsg );
00677 
00678   return ;
00679 }
00680 
00683 void Player::performPenalty( )
00684 {
00685   VecPosition   pos;
00686   int           iSide = ( WM->getSide() == WM->getSidePenalty() ) ? -1 : 1;
00687   VecPosition   posPenalty( iSide*(52.5 - SS->getPenDistX()), 0.0 );
00688   VecPosition   posAgent = WM->getAgentGlobalPosition();
00689   AngDeg        angBody  = WM->getAgentGlobalBodyAngle();
00690 
00691   SoccerCommand soc(CMD_ILLEGAL);
00692   static PlayModeT pmPrev = PM_ILLEGAL;
00693 
00694   // raise number of penalties by one when a penalty is taken
00695   if(
00696     ( WM->getSide() == SIDE_LEFT && 
00697       pmPrev != PM_PENALTY_SETUP_LEFT && 
00698       WM->getPlayMode() == PM_PENALTY_SETUP_LEFT )
00699     ||
00700     ( WM->getSide() == SIDE_RIGHT && 
00701       pmPrev != PM_PENALTY_SETUP_RIGHT && 
00702       WM->getPlayMode() == PM_PENALTY_SETUP_RIGHT ) )
00703    m_iPenaltyNr++;
00704 
00705   // start with player 11 and go downwards with each new penalty
00706   // if we take penalty 
00707   if( WM->isPenaltyUs() && WM->getPlayerNumber() == (11 - (m_iPenaltyNr % 11)))
00708   {
00709      if( WM->getPlayMode() == PM_PENALTY_SETUP_LEFT ||
00710          WM->getPlayMode() == PM_PENALTY_SETUP_RIGHT )
00711      {
00712        pos = posPenalty - VecPosition( iSide*2.0, 0 );
00713        if( fabs( posAgent.getX() ) > fabs( pos.getX() ) )
00714          pos = posPenalty;
00715        if( pos.getDistanceTo( posAgent ) < 0.6 )
00716        {
00717          pos = posPenalty;
00718          if(  fabs( VecPosition::normalizeAngle( 
00719                    (pos-posAgent).getDirection() - angBody ) ) > 20 )
00720            soc = turnBodyToPoint( pos );
00721        }
00722        //  pos = WM->getAgentGlobalPosition();
00723      }
00724      else if( ( WM->getPlayMode() == PM_PENALTY_READY_LEFT ||
00725                 WM->getPlayMode() == PM_PENALTY_READY_RIGHT ||
00726                 WM->getPlayMode() == PM_PENALTY_TAKEN_LEFT ||
00727                 WM->getPlayMode() == PM_PENALTY_TAKEN_RIGHT 
00728                 )
00729               && WM->isBallKickable() )
00730      {
00731        soc = kickTo(VecPosition(iSide*52.5,((drand48()<0.5)?1:-1)*5.9 ),2.7);
00732      }
00733      else
00734        pos = posPenalty;
00735   }
00736   else if( formations->getPlayerType() == PT_GOALKEEPER )
00737   {
00738     if( WM->getAgentViewAngle() != VA_NARROW )
00739       ACT->putCommandInQueue( 
00740                  SoccerCommand( CMD_CHANGEVIEW, VA_NARROW, VQ_HIGH ));
00741 
00742     // is penalty them, stop it, otherwise go to outside field
00743     pos = posPenalty;
00744     if( WM->isPenaltyThem( ) )
00745     {
00746       pos = VecPosition( iSide*(52.5 - 2.0), 0.0 );
00747       if( SS->getPenAllowMultKicks() == false )
00748       {
00749         if( WM->getPlayMode() == PM_PENALTY_TAKEN_LEFT ||
00750             WM->getPlayMode() == PM_PENALTY_TAKEN_RIGHT )
00751         {
00752           if( WM->isBallCatchable( ) )
00753             soc = catchBall();
00754           else
00755             soc = intercept( true );
00756         }
00757       }
00758       else if( pos.getDistanceTo( posAgent ) < 1.0 )
00759         soc = turnBodyToPoint( VecPosition( 0,0) ) ;
00760       else
00761         soc = moveToPos( pos, 25 );
00762     }
00763     else
00764       pos.setVecPosition( iSide * ( PITCH_LENGTH/2.0 + 2 ) , 25 );
00765   }
00766   else
00767   {
00768     pos = VecPosition( 5.0,
00769                        VecPosition::normalizeAngle( 
00770                          iSide*(50 + 20*WM->getPlayerNumber())),
00771                        POLAR );
00772   }
00773 
00774 
00775   if( soc.isIllegal() && 
00776       WM->getAgentGlobalPosition().getDistanceTo( pos ) < 0.8 )
00777   {
00778     soc = turnBodyToPoint( posPenalty  );    
00779   }
00780   else if( soc.isIllegal() )
00781   {
00782     soc = moveToPos( pos, 10);
00783   }
00784   if( WM->getAgentStamina().getStamina() < 
00785       SS->getRecoverDecThr()*SS->getStaminaMax() + 500 &&
00786     soc.commandType == CMD_DASH)
00787     soc.dPower = 0;
00788   
00789   ACT->putCommandInQueue( soc );
00790   ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00791 
00792   pmPrev = WM->getPlayMode();
00793 }
00794 
00800 ObjectT Player::getPlayerTypeRole(int index) {
00801         ObjectT o;
00802         switch(index) {
00803         
00804                 // GOALIE agent
00805                 case 0:
00806                         o = OBJECT_TEAMMATE_1;
00807                 break;
00808                 
00809                 // moji TEAMMATES
00810                 case 1:
00811                         o = OBJECT_TEAMMATE_2;
00812                 break;
00813                 case 2:
00814                         o = OBJECT_TEAMMATE_3;
00815                 break;
00816                 case 3:
00817                         o = OBJECT_TEAMMATE_4;
00818                 break;
00819                 case 4:
00820                         o = OBJECT_TEAMMATE_5;
00821                 break;
00822                 case 5:
00823                         o = OBJECT_TEAMMATE_6;
00824                 break;
00825                 case 6:
00826                         o = OBJECT_TEAMMATE_7;
00827                 break;
00828                 case 7:
00829                         o = OBJECT_TEAMMATE_8;
00830                 break;
00831                 case 8:
00832                         o = OBJECT_TEAMMATE_9;
00833                 break;
00834                 case 9:
00835                         o = OBJECT_TEAMMATE_10;
00836                 break;
00837                 case 10:
00838                         o = OBJECT_TEAMMATE_11;
00839                 break;
00840                 default:
00841                         o = OBJECT_TEAMMATE_1;
00842         }
00843         return o;
00844 }
00845 
00851 int Player::getPlayerIndexRole(ObjectT o) {
00852         int index;
00853         switch(o) {
00854         
00855                 // GOALIE agent
00856                 case OBJECT_TEAMMATE_1:
00857                         index = 0;
00858                 break;
00859                 
00860                 // moji TEAMMATES
00861                 case OBJECT_TEAMMATE_2:
00862                         index = 1;
00863                 break;
00864                 case OBJECT_TEAMMATE_3:
00865                         index = 2;
00866                 break;
00867                 case OBJECT_TEAMMATE_4:
00868                         index = 3;
00869                 break;
00870                 case OBJECT_TEAMMATE_5:
00871                         index = 4;
00872                 break;
00873                 case OBJECT_TEAMMATE_6:
00874                         index = 5;
00875                 break;
00876                 case OBJECT_TEAMMATE_7:
00877                         index = 6;
00878                 break;
00879                 case OBJECT_TEAMMATE_8:
00880                         index = 7;
00881                 break;
00882                 case OBJECT_TEAMMATE_9:
00883                         index = 8;
00884                 break;
00885                 case OBJECT_TEAMMATE_10:
00886                         index = 9;
00887                 break;
00888                 case OBJECT_TEAMMATE_11:
00889                         index = 10;
00890                 break;
00891                 default:
00892                         index = -1;
00893         }
00894         return index;
00895 }
00896 
00900 RoleCG * Player::getPlayerRoles() {
00901         
00902         // potencialy pre aktivneho hraca
00903         double activePotencial[11];
00904         
00905         // potencialy pre rolu receiver
00906         double receiverPotencial[11];
00907         
00908         // isCloseToBall: pre kazdeho hraca su 3 mozne stavy
00909         // 1  - nachadza sa v okruhu 6 metrov od lopty, je pri nej tak blizko ze mozeano, je tak blizko pri lopte, ze moze do nej kopnut
00910         // 0  - nachadza sa v okruhu 6 mestrov od lopty, ale nemoze do nej kopnut (loptu ma napr. super a pod...)
00911         // -1 - nachadza sa mimo okruhu 6 metrov
00912         
00913         int isCloseToBall[11];
00914         
00915         // role jednotlivym hracom, na 11-tej pozicii je moja rola
00916         RoleCG * roles = new RoleCG[11];
00917         
00918         int iIndex;
00919         int index;
00920         
00921         double vR = SS->getPlayerSpeedMax();
00922         double t;
00923         
00924         // na zaciatku su potencialy pre role rovne 0.0
00925         for(int i=0; i < 11; i++) {
00926                  activePotencial[i] = 0.0;
00927                  receiverPotencial[i] = 0.0;
00928                  isCloseToBall[i] = -1;
00929                  roles[i] = NO_ROLE;
00930         }
00931         
00932         // pridelime rolu GOALIE
00933         roles[0] = GOALIE;
00934         
00935         // zistime si poziciu lopty a jej rychlost      
00936         VecPosition b0 = WM->getBallPos();
00937         VecPosition v0 = WM->getGlobalVelocity(OBJECT_BALL);
00938         
00939         /*
00940         // ak som nevidel loptu
00941         if(v0.getX() == UnknownDoubleValue)     {
00942                 // TODO som passive
00943         }
00944         */
00945 
00946         // prejdeme cez mnozinu mojich spoluhracov
00947     ObjectSetT set = OBJECT_SET_TEAMMATES_NO_GOALIE;
00948     
00949     // a iterujeme ...
00950     for(ObjectT o = WM->iterateObjectStart(iIndex, set); o != OBJECT_ILLEGAL; o = WM->iterateObjectNext(iIndex, set)) 
00951     {           
00952         index = getPlayerIndexRole(o);
00953         
00954         // ak nastane nejaka chyba alebo pre brankara potencial nepocitame
00955         if(index != 0) {
00956                         // zistime si poziciu hraca na ihrisku
00957                 VecPosition r0 = WM->getGlobalPosition(o);
00958                         
00959                         // vypocitaj najmensi cas zachytenia lopty                                              
00960                 t = ArsToolbox::computeLeastInterceptTime(b0, v0, r0, vR, 2.0);
00961 
00962                         // vypocitaj aky ma hrac potencial vzhladom k role ACTIVE
00963                 activePotencial[index] = 1.0 / t;
00964                 
00965                 // musime urcit, ci bude hrac PASSER alebo INTERCEPTOR
00966                         double r0ToBallDistance = (r0 - b0).getMagnitude();
00967                         
00968                         // ak agent je tak blizko ze moze kopnut do lopty priamo
00969                 if((r0ToBallDistance < SS->getMaximalKickDist()) )
00970                 {
00971                         isCloseToBall[index] = 1;
00972                 }
00973                 // teraz sa pozrieme ci je od nej vzdialeny aspon do 10 metrov ak do nej nemoze priamo kopnut
00974                 else if(r0ToBallDistance < 10)
00975                 {
00976                         isCloseToBall[index] = 0;
00977                 }
00978                 else
00979                 {
00980                         isCloseToBall[index] = -1;
00981                 }
00982         }
00983     }
00984     WM->iterateObjectDone(iIndex);
00985 
00986         // spoluhraci su urceni, este to iste urcim pre seba
00987         VecPosition r0 = WM->getAgentGlobalPosition();
00988           
00989         // nasledovne dva riadky netreba, lebo index 11 neexistuje a informacie o mne mam ulozene tiez v tom poli                                       
00990         //t = ArsToolbox::computeLeastInterceptTime(b0, v0, r0, vR, 2.0);
00991         //activePotencial[11] = 1.0 / t;
00992 
00993         double r0ToBallDistance = (r0 - b0).getMagnitude();
00994 
00995         if((r0ToBallDistance < SS->getMaximalKickDist()) ) {
00996                 isCloseToBall[index] = 1;
00997         } else if(r0ToBallDistance < 10) {
00998                 isCloseToBall[index] = 0;
00999         } else {
01000                 isCloseToBall[index] = -1;
01001         }
01002         
01003         // potencialy su vyratane, konecne urcime hraca s rolou ACTIVE
01004         
01005         // urcime hraca s rolou ACTIVE
01006         double maxValue = activePotencial[0];
01007         int maxI = 0;
01008 
01009         // zacneme od 1, pretoze brankar (index == 0) nemoze byt ACTIVE 
01010         for(int i=1; i < 11; i++) {
01011                 if(activePotencial[i] > maxValue) {
01012                         maxValue = activePotencial[i];
01013                         maxI = i;       
01014                 }
01015         }
01016         
01017         // nikto by nemal vacsi potencial ako brankar?
01018         // to by nemalo nastat, ale ajtak to osetrime
01019         if(maxI == 0) {
01020                 for(int i=1; i < 11; i++) {
01021                         roles[i] = PASSIVE;
01022                 }
01023                 
01024                 return roles;
01025         }
01026         else {
01027                 if(isCloseToBall[maxI] == 1) {
01028                         roles[maxI] = ACTIVE_PASSER;
01029                 } else if(isCloseToBall[maxI] == 0) {
01030                         roles[maxI] = ACTIVE_INTERCEPTOR;
01031                 } else {
01032                         // ak nemoze byt ziadny active, nemoze byt ani ziadny interceptor
01033                         for(int i=1; i < 11; i++)
01034                                 roles[i] = PASSIVE;
01035                 
01036                         return roles;
01037                 }
01038         }
01039         
01040         // mame pridelene ROLU ACTIVE, teraz treba pridelit role RECEIVER,
01041         // ak sa teda daju pridelit
01042 
01043         // pridelime role RECEIVER
01044     for( ObjectT o = WM->iterateObjectStart(iIndex, set);
01045          o != OBJECT_ILLEGAL;
01046          o = WM->iterateObjectNext(iIndex, set)) 
01047     {           
01048         index = getPlayerIndexRole(o);
01049         
01050         if(index != 0) {
01051                 
01052                 // ak spoluhrac este nema pridelenu rolu
01053                 if(roles[index] == NO_ROLE) {
01054                                 
01055                                 // zistime si poziciu hraca na ihrisku
01056                         VecPosition r0 = WM->getGlobalPosition(o);
01057                         
01058                                 // d_ib
01059                                 double r0ToBallDistance = (r0 - b0).getMagnitude();
01060 
01061                                 // d_ig
01062                                 double r0ToOpponentGoalDistance = (r0 - WM->getGlobalPosition(OBJECT_GOAL_R)).getMagnitude();
01063                                 
01064                                 if(r0ToBallDistance <= 28)
01065                                         receiverPotencial[index] = ((1 / this->getMax(1, r0ToOpponentGoalDistance)) + 1);
01066                                 else
01067                                         receiverPotencial[index] = (1 / this->getMax(1, r0ToOpponentGoalDistance));
01068                 }
01069         }
01070     }
01071 
01072         // nasledovne riadky podla mna netreba, lebo rola pre mna je uz vypocitana v tom poli...
01073         // este pre seba urcim potencial k role RECEIVER ak nemam este ziadnu rolu
01074         /*if(roles[11] == NO_ROLE)
01075         {
01076                 // zistime si poziciu hraca na ihrisku
01077         VecPosition r0 = WM->getAgentGlobalPosition();
01078                         
01079                 // d_ib
01080                 double r0ToBallDistance = (r0 - b0).getMagnitude();
01081 
01082                 // d_ig
01083                 double r0ToOpponentGoalDistance = (r0 - WM->getGlobalPosition(OBJECT_GOAL_R)).getMagnitude();
01084                                 
01085                 if(r0ToBallDistance <= 28)
01086                         receiverPotencial[11] = ((1 / this->getMax(1, r0ToOpponentGoalDistance)) + 1);
01087                 else
01088                         receiverPotencial[11] = (1 / this->getMax(1, r0ToOpponentGoalDistance));
01089         }*/
01090 
01091         // ok, potencialy su priradene, priradime role RECEIVER
01092         int maxIReceiver;
01093         
01094         for(int j=0; j < 2; j++)
01095         {
01096                 double maxValueReceiver = 0.0;
01097         
01098                 for(int i=1; i < 11; i++)
01099                 {
01100                         if(roles[i] == NO_ROLE)
01101                         {
01102                                 if(receiverPotencial[i] > maxValueReceiver)
01103                                 {
01104                                         maxIReceiver = i;
01105                                         maxValueReceiver = receiverPotencial[i];
01106                                 }
01107                         }
01108                 }
01109                 
01110                 roles[maxIReceiver] == RECEIVER;
01111         } 
01112     
01113     return roles;
01114 }
01115 
01120 RoleCG Player::getMyRole()
01121 {
01122         RoleCG * allPlayerRoles = this->getPlayerRoles();
01123         int index = getPlayerIndexRole(WM->getAgentObjectType());
01124          
01125         return allPlayerRoles[index];
01126 }
01127 
01128 double Player::getMax(double val1, double val2)
01129 {
01130         if(val1 > val2)
01131                 return val1;
01132         else
01133                 return val2;
01134 }
01135 
01141 double Player::transformGlobalDirectionToAngleCG(DirCG globalDirection)
01142 {
01143         switch(globalDirection)
01144         {
01145                 case N:
01146                         return WM->getGlobalAngle(OBJECT_GOAL_R);
01147                         break;
01148                 case NE:
01149                         return WM->getGlobalAngle(OBJECT_FLAG_R_B);
01150                         break;          
01151                 case E:
01152                         return WM->getGlobalAngle(OBJECT_FLAG_C_B);
01153                         break;          
01154                 case SE:
01155                         return WM->getGlobalAngle(OBJECT_FLAG_L_B);
01156                         break;          
01157                 case S:
01158                         return WM->getGlobalAngle(OBJECT_GOAL_L);
01159                         break;          
01160                 case SW:
01161                         return WM->getGlobalAngle(OBJECT_FLAG_L_T);
01162                         break;          
01163                 case W:
01164                         return WM->getGlobalAngle(OBJECT_FLAG_C_T);
01165                         break;          
01166                 case NW:
01167                         return WM->getGlobalAngle(OBJECT_FLAG_R_T);
01168                         break;          
01169                 default:
01170                         return 0.0;
01171         }
01172         
01173         return 0.0;
01174 }
01175 
01181 double Player::valueRuleInterc1(PlayerActionCG agentAction)
01182 {
01183         if(agentAction.getActionType() == INTERCEPT)
01184                 return 10.0;
01185 }
01186 
01196 double Player::valueRulePasser1(RoleCG * playerRoles, int teammateIndex, PlayerActionCG agentAction,
01197                                                 PlayerActionCG teammateAction,
01198                                                 DirCG passDirection)
01199 {
01200         // if an incorrect input has been specified then the value of this rule is 0.0
01201         // <1-10> is allowed
01202         if(teammateIndex < 1 || teammateIndex > 10)
01203                 return 0.0;
01204         
01205         // conditions of the value rule
01206         if(      
01207                  playerRoles[teammateIndex] == RECEIVER &&
01208                  
01209                  // TODO: neni este implementovana
01210                  //(WM->isPassBlockedCG(11, teammateIndex, passDirection) == false) &&
01211                  (isPassBlockedCG(getPlayerIndexRole(WM->getAgentObjectType()), teammateIndex, passDirection) == false) &&
01212 
01213                   
01214                  (agentAction.getActionType() == LEADING_PASS_TO &&
01215                   agentAction.getTeammateIndex() == teammateIndex &&
01216                   agentAction.getDirection() == passDirection) &&
01217                  
01218                  (teammateAction.getActionType() == MOVE_TO &&
01219                   teammateAction.getDirection() == passDirection)
01220          )
01221 
01222                 return uCG(teammateIndex, passDirection);
01223 }
01224 
01231 double Player::valueRulePasser2(PlayerActionCG agentAction, DirCG emptySpaceDirection)
01232 {
01233         if(
01234                 isEmptySpace(getPlayerIndexRole(WM->getAgentObjectType()), emptySpaceDirection) &&
01235                 (agentAction.getActionType() == DRIBBLE &&
01236                  agentAction.getDirection() == emptySpaceDirection)
01237                  
01238           )
01239                 return 2.0;
01240 }
01241 
01247 double Player::valueRulePasser3(PlayerActionCG agentAction)
01248 {
01249         if(
01250                 agentAction.getActionType() == DRIBBLE
01251                 
01252           )
01253                   return 0.1; 
01254 }
01255 
01261 bool Player::isInFrontOfGoalCG(VecPosition pos)
01262 {
01263    ObjectT objFlag = (WM->getSide() == SIDE_LEFT )
01264                                ?  OBJECT_FLAG_P_R_C
01265                                :  OBJECT_FLAG_P_L_C;
01266 
01267    VecPosition posFlag = SoccerTypes::getGlobalPositionFlag(objFlag,WM->getSide());
01268  
01269    if (pos.getX() > posFlag.getX() &&
01270        fabs(pos.getY()) < PENALTY_AREA_WIDTH/4.0)
01271      return true;
01272  
01273    return false;
01274 }
01275 
01281 double Player::valueRulePasser4(PlayerActionCG agentAction)
01282 {
01283         if(
01284                 isInFrontOfGoalCG(WM->getAgentGlobalPosition()) &&
01285 
01286                 WM->isBallKickable() &&
01287                 
01288                 (agentAction.getActionType() == SCORE)
01289           )
01290                 return 10.0;
01291 }
01292 
01302 double Player::valueRuleReceiver1(RoleCG * playerRoles, int teammateIndex, PlayerActionCG agentAction,
01303                                                           PlayerActionCG teammateAction,
01304                                                           DirCG passDirection)
01305 {
01306         if(      
01307                  playerRoles[teammateIndex] == ACTIVE_INTERCEPTOR &&
01308 
01309                  // TODO: neni este implementovana
01310                  //(WM->isPassBlockedCG(11, teammateIndex, passDirection) == false) &&
01311 
01312                  (teammateAction.getActionType() == INTERCEPT) &&
01313                  
01314                  (agentAction.getActionType() == MOVE_TO &&
01315                   agentAction.getDirection() == passDirection)
01316          )
01317                 return uCG(getPlayerIndexRole(WM->getAgentObjectType()), passDirection);
01318 }
01319 
01332 double Player::valueRuleReceiver2(RoleCG * playerRoles, int teammateIndex1, int teammateIndex2,
01333                                                                   PlayerActionCG agentAction,
01334                                                               PlayerActionCG teammateAction1,
01335                                                                   DirCG passDirection1,
01336                                                                   PlayerActionCG teammateAction2,
01337                                                                   DirCG passDirection2)
01338 {
01339         if(      
01340                  playerRoles[teammateIndex2] == RECEIVER &&
01341 
01342                  // TODO: neni este implementovana
01343                  //(WM->isPassBlockedCG(teammateIndex2, 11, passDirection1) == false) &&
01344 
01345                  (teammateAction1.getActionType() == LEADING_PASS_TO &&
01346                   teammateAction1.getTeammateIndex() == teammateIndex2 &&
01347                   teammateAction1.getDirection() == passDirection2) &&
01348                   
01349                  (teammateAction2.getActionType() == MOVE_TO &&
01350                   teammateAction2.getDirection() == passDirection2) &&
01351                   
01352                  (agentAction.getActionType() == MOVE_TO &&
01353                   agentAction.getDirection() == passDirection1)
01354          )
01355                 return uCG(getPlayerIndexRole(WM->getAgentObjectType()), passDirection1);
01356 }
01357 
01363 double Player::valueRuleReceiver3(PlayerActionCG agentAction)
01364 {
01365         if(      
01366                  agentAction.getActionType() == MOVE_TO_STRAT_POS
01367            )
01368                 return 1.0;     
01369 }
01370 
01376 double Player::valueRulePassive1(PlayerActionCG agentAction)
01377 {
01378         if(      
01379                  agentAction.getActionType() == MOVE_TO_STRAT_POS
01380            )
01381                 return 1.0;     
01382 }
01383 
01388 PlayerActionCG * Player::getOptimalCommonAction()
01389 {
01390         PlayerActionCG * optimalPlayerActions;
01391         
01392         // priradime hracom role
01393         RoleCG * playerRoles = this->getPlayerRoles();
01394 
01395         // najdeme optimalnu spolocnu akciu pre vsetkych agentov
01396         optimalPlayerActions = variableEliminationAlgorithmCG(playerRoles);
01397         
01398         return optimalPlayerActions;
01399 }
01400 
01401 
01406 PlayerActionCG * Player::variableEliminationAlgorithmCG(RoleCG * playerRoles)
01407 {
01408         /*
01409         // vybrane akcie agentov v doprednom prechode - faza eliminacie agentov
01410         PlayerActionCG * playerToEliminateAction[12];
01411         
01412         for(int i=0; i < 12; i++)
01413         {
01414                 playerToEliminateAction[12] = new PlayerActionCG();
01415         }
01416         
01417         // vsetkych agentov postupne eliminujeme z grafu v poradi zlava doprava (okrem brankara)
01418         for(int playerToEliminateIndex=1; playerToEliminateIndex < 12; playerToEliminateIndex++)
01419         {
01420                 // zistime si aku ma agent rolu
01421                 RoleCG agentToEliminateRole = playerRoles[playerToEliminateIndex];
01422                 
01423                 if(agentToEliminateRole == ACTIVE_PASSER || agentToEliminateRole == ACTIVE_INTERCEPTOR || agentToEliminateRole == RECEIVER)
01424                 {                                               
01425                         // musime definovat ake prislusne akcie bude mat agent urceny na eliminaciu s ohladom na jeho rolu
01426                         PlayerActionTypeCG possibleAgentToEliminateActions[POSSIBLE_PLAYER_ACTION_TYPES_CG_NO];
01427                         int possibleAgentToEliminateActionsNo;
01428                                                 
01429                         switch(agentToEliminateRole)
01430                         {
01431                                 case ACTIVE_PASSER:
01432                                         possibleAgentToEliminateActions[0] = PASS_TO;
01433                                         possibleAgentToEliminateActions[1] = DRIBBLE;
01434                                         possibleAgentToEliminateActions[2] = CLEAR_BALL;
01435                                         possibleAgentToEliminateActions[3] = SCORE;
01436                                                                 
01437                                         possibleAgentToEliminateActionsNo = 4;                                  
01438                                         break;
01439                                                                 
01440                                 case ACTIVE_INTERCEPTOR:
01441                                         possibleAgentToEliminateActions[0] = INTERCEPT;
01442                                                                 
01443                                         possibleAgentToEliminateActionsNo = 1;                                                  
01444                                         break;
01445 
01446                                 case RECEIVER:
01447                                         possibleAgentToEliminateActions[0] = MOVE_TO;
01448                                         possibleAgentToEliminateActions[1] = MOVE_TO_STRAT_POS;
01449                                                                                                                                 
01450                                         possibleAgentToEliminateActionsNo = 2;                                  
01451                                         break;
01452                                                         
01453                                 default:
01454                                         possibleAgentToEliminateActionsNo = 0;
01455                         }
01456 
01457                         // pre kazdeho spoluhraca agenta urceneho na eliminaciu spoluhraca
01458                         for(int teammateIndex=1; teammateIndex < 12; teammateIndex++)
01459                         {
01460 
01461                                 // okrem agenta urceneho na eliminaciu
01462                                 if(playerToEliminateIndex != teammateIndex)
01463                                 {
01464 
01465 
01466                                                 // akcia agenta na eliminaciu z koordinacneho grafu
01467                                                 PlayerActionCG * playerToEliminateAction;
01468                                                 
01469                                                 // musime definovat ake prislusne akcie bude mat agent urceny na eliminaciu s ohladom na jeho rolu
01470                                                 PlayerActionTypeCG possibleAgentToEliminateActions[POSSIBLE_PLAYER_ACTION_TYPES_CG_NO];
01471                                                 int possibleAgentToEliminateActionsNo;
01472 
01473                                                                         switch(agentToEliminateRole)
01474                                                                         {
01475                                                                                 case ACTIVE_PASSER:
01476                                                                                         possibleAgentToEliminateActions[0] = PASS_TO;
01477                                                                                         possibleAgentToEliminateActions[1] = DRIBBLE;
01478                                                                                         possibleAgentToEliminateActions[2] = CLEAR_BALL;
01479                                                                                         possibleAgentToEliminateActions[3] = SCORE;
01480                                                                 
01481                                                                                         possibleAgentToEliminateActionsNo = 4;                                  
01482                                                                                         break;
01483                                                                 
01484                                                                                         case ACTIVE_INTERCEPTOR:
01485                                                                                                 possibleAgentToEliminateActions[0] = INTERCEPT;
01486                                                                         
01487                                                                                                 possibleAgentToEliminateActionsNo = 1;                                                  
01488                                                                                         break;
01489 
01490                                                                                 case RECEIVER:
01491                                                                                         possibleAgentToEliminateActions[0] = MOVE_TO;
01492                                                                                         possibleAgentToEliminateActions[1] = MOVE_TO_STRAT_POS;
01493                                                                                                                                 
01494                                                                                         possibleAgentToEliminateActionsNo = 2;                                  
01495                                                                                         break;
01496                                                         
01497                                                                                 default:
01498                                                                                         possibleAgentToEliminateActionsNo = 0;
01499                                                                         }
01500 
01501 
01502 
01503 
01504 
01505 
01506 
01507 
01508 
01509 
01510 
01511 
01512                                         // zistime si jeho rolu
01513                                         RoleCG teammateRole = playerRoles[teammateIndex];
01514                                         
01515                                         // ak ma rolu, ktora nas zaujima a s ktorou my ako agent mozeme koordinovat nase akcie
01516                                         if(teammateRole == ACTIVE_PASSER || teammateRole == ACTIVE_INTERCEPTOR || teammateRole == RECEIVER)     
01517                                         {
01518                                                 // maximalny vynos, ktory hrac urceny na eliminaciu moze dosiahnut
01519                                                 double maxValue = 0.0;
01520                                                         
01521                                                 
01522                                                 // skusime vsetky mozne kombinacie mojich akcii vzhladom k zvolenym akciam mojich spoluhracov
01523                                                 for(int actionIndex=0; actionIndex < possibleAgentToEliminateActionsNo; actionIndex++)
01524                                                 {
01525                                                         if(possibleAgentToEliminateActions[actionIndex] == PASS_TO)
01526                                                         {
01527                                                                 playerToEliminateAction = new PlayerActionCG();
01528                                                                 playerToEliminateAction->setActionType(PASS_TO);
01529                                                                 
01530                                                                 DirCG dir = {N, NW, W, SW, S, SE, E, NE};
01531                                                                 int possibleDirectionsNo = 8;
01532 
01533                                                                 for(int directionIndex=0; directionIndex < possibleDirectionsNo; directionIndex++) 
01534                                                                 {
01535 
01536 
01537 
01538                                                                         // v tomto okamihu uz mame zlozenu celu akciu agenta urceneho na eliminaciu
01539                                                                         // teraz zlozime akcie jeho 
01540                                                                         
01541                                                                         for(int teammateActionIndex=0; teammateActionIndex < 
01542                                                                 }
01543                                         
01544                                                                 
01545                                                         }
01546                                                         
01547                                                         
01548                                                         
01549                                                 }
01550                                                 
01551                                                 
01552                                                 
01553                                                 
01554                                                 double rulesCombinationValue = 0.0;
01555                                                 
01556                                                 
01557                                                 
01558                                                 
01559                                                 rulesCombinationValue += valueRulePasser1(playerRoles, teammateIndex, agentAction, teammateAction, passDirection); 
01560                                         }
01561                                 }                                        
01562                         }
01563                 }
01564                                         
01565                                         
01566                                         
01567                                 break;
01568                         
01569                 }
01570         }
01571         
01572         */
01573         
01574         return NULL;
01575 }
01576 
01585 bool Player::isPassBlockedCG(int playerIndex, int teammateIndex, DirCG passDirection) {
01586 
01587         return false;
01588 }
01589 
01597 bool Player::isEmptySpace(int playerIndex, DirCG direction) {
01598         
01599         return true;
01600 }
01601 
01609 double Player::uCG(int teammateIndex, DirCG passDirection) {
01610         return 6;
01611 }

Generated on Thu Apr 26 22:45:27 2007 for GangOfSix(GOS)-RoboCupTeamProject by  doxygen 1.5.1-p1