00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00049 #include "Player.h"
00050 #include "Parse.h"
00051
00052 #ifndef WIN32
00053 #include <sys/poll.h>
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
00094
00095 #ifdef WIN32
00096 Sleep( formations->getPlayerInFormation()*500 );
00097 #else
00098 poll( 0, 0, formations->getPlayerInFormation()*500 );
00099 #endif
00100
00101
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
00126
00127 if( WM->waitForNewInformation() == false )
00128 bContLoop = false;
00129
00130
00131 sprintf( str, "(clang (ver 8 8))" );
00132 ACT->sendMessage( str );
00133
00134 while( bContLoop )
00135 {
00136 Log.logWithTime( 3, " start update_all" );
00137
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( ) )
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 )
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
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
00215
00216 if( WM->waitForNewInformation() == false )
00217 bContLoop = false;
00218 }
00219
00220
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
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
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 );
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':
00364 WM->showQueuedCommands();
00365 break;
00366 case 'c':
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':
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':
00381 showStringCommands( cout );
00382 return true;
00383 case 'k':
00384 socCommand.commandType = CMD_KICK;
00385 if( str[1] == 'a' )
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':
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':
00405 socCommand.commandType = CMD_TURNNECK;
00406 socCommand.dAngle = Parse::parseFirstDouble( &str );
00407 break;
00408 case 'o':
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':
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':
00427 bContLoop = false;
00428 return true;
00429 case 's':
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':
00441 socCommand.commandType = CMD_TURN;
00442 socCommand.dAngle = Parse::parseFirstDouble( &str );
00443 break;
00444 case 'v':
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':
00454 WM->show();
00455 return true;
00456 default:
00457 ACT->sendMessage( str );
00458 return true;
00459 }
00460 if( socCommand.commandType != CMD_ILLEGAL )
00461 ACT->putCommandInQueue( socCommand );
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
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
00512
00513 obj = WM->getClosestInSetTo( OBJECT_SET_TEAMMATES,OBJECT_BALL,&dDist);
00514 if( dDist < SS->getVisibleDistance() &&
00515 obj != WM->getAgentObjectType() )
00516 return false;
00517
00518
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 )
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
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 (
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
00558
00559 sprintf( strMsg, "%c", 'a' + WM->getCurrentCycle()%10 );
00560
00561
00562
00563
00564
00565 int iOffside = (int)WM->getOffsideX();
00566 if( iOffside < 26 )
00567 sprintf( strTmp, "%c", 'a' + iOffside );
00568 else
00569 sprintf( strTmp, "%c", 'A' + max(iOffside - 26, 25) );
00570 strcat( strMsg, strTmp );
00571
00572
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
00591
00592
00593
00594
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
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
00649
00650 sprintf( strMsg, "%c", 'a' + (WM->getCurrentCycle()+iDiff)%10 );
00651
00652
00653
00654
00655
00656 int iOffside = (int)( WM->getOffsideX( false ) - 1.0 );
00657 if( iOffside < 26 )
00658 sprintf( strTmp, "%c", 'a' + max( 0, iOffside) );
00659 else
00660 sprintf( strTmp, "%c", 'A' + min(iOffside - 26, 25) );
00661 strcat( strMsg, strTmp );
00662
00663
00664
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
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
00706
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
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
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
00805 case 0:
00806 o = OBJECT_TEAMMATE_1;
00807 break;
00808
00809
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
00856 case OBJECT_TEAMMATE_1:
00857 index = 0;
00858 break;
00859
00860
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
00903 double activePotencial[11];
00904
00905
00906 double receiverPotencial[11];
00907
00908
00909
00910
00911
00912
00913 int isCloseToBall[11];
00914
00915
00916 RoleCG * roles = new RoleCG[11];
00917
00918 int iIndex;
00919 int index;
00920
00921 double vR = SS->getPlayerSpeedMax();
00922 double t;
00923
00924
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
00933 roles[0] = GOALIE;
00934
00935
00936 VecPosition b0 = WM->getBallPos();
00937 VecPosition v0 = WM->getGlobalVelocity(OBJECT_BALL);
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 ObjectSetT set = OBJECT_SET_TEAMMATES_NO_GOALIE;
00948
00949
00950 for(ObjectT o = WM->iterateObjectStart(iIndex, set); o != OBJECT_ILLEGAL; o = WM->iterateObjectNext(iIndex, set))
00951 {
00952 index = getPlayerIndexRole(o);
00953
00954
00955 if(index != 0) {
00956
00957 VecPosition r0 = WM->getGlobalPosition(o);
00958
00959
00960 t = ArsToolbox::computeLeastInterceptTime(b0, v0, r0, vR, 2.0);
00961
00962
00963 activePotencial[index] = 1.0 / t;
00964
00965
00966 double r0ToBallDistance = (r0 - b0).getMagnitude();
00967
00968
00969 if((r0ToBallDistance < SS->getMaximalKickDist()) )
00970 {
00971 isCloseToBall[index] = 1;
00972 }
00973
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
00987 VecPosition r0 = WM->getAgentGlobalPosition();
00988
00989
00990
00991
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
01004
01005
01006 double maxValue = activePotencial[0];
01007 int maxI = 0;
01008
01009
01010 for(int i=1; i < 11; i++) {
01011 if(activePotencial[i] > maxValue) {
01012 maxValue = activePotencial[i];
01013 maxI = i;
01014 }
01015 }
01016
01017
01018
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
01033 for(int i=1; i < 11; i++)
01034 roles[i] = PASSIVE;
01035
01036 return roles;
01037 }
01038 }
01039
01040
01041
01042
01043
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
01053 if(roles[index] == NO_ROLE) {
01054
01055
01056 VecPosition r0 = WM->getGlobalPosition(o);
01057
01058
01059 double r0ToBallDistance = (r0 - b0).getMagnitude();
01060
01061
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
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
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
01201
01202 if(teammateIndex < 1 || teammateIndex > 10)
01203 return 0.0;
01204
01205
01206 if(
01207 playerRoles[teammateIndex] == RECEIVER &&
01208
01209
01210
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
01310
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
01343
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
01393 RoleCG * playerRoles = this->getPlayerRoles();
01394
01395
01396 optimalPlayerActions = variableEliminationAlgorithmCG(playerRoles);
01397
01398 return optimalPlayerActions;
01399 }
01400
01401
01406 PlayerActionCG * Player::variableEliminationAlgorithmCG(RoleCG * playerRoles)
01407 {
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
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 }