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
00048 #include "Player.h"
00049 #include "Parse.h"
00050 #include <sys/poll.h>
00051
00052
00062 Player::Player( ActHandler* act, WorldModel *wm, ServerSettings *ss,
00063 PlayerSettings *ps,
00064 Formations *fs, char* strTeamName, double dVersion, int iReconnect )
00065
00066 {
00067 char str[MAX_MSG];
00068
00069 ACT = act;
00070 WM = wm;
00071 SS = ss;
00072 PS = ps;
00073 formations = fs;
00074 bContLoop = true;
00075 WM->setTeamName( strTeamName );
00076 m_timeLastSay = -5;
00077
00078
00079
00080 poll( 0, 0, formations->getPlayerInFormation()*100 );
00081
00082
00083 if( iReconnect != -1 )
00084 sprintf( str, "(reconnect %s %d)", strTeamName, iReconnect );
00085 else if( formations->getPlayerType() == PT_GOALKEEPER )
00086 sprintf( str, "(init %s (version %f) (goalie))", strTeamName, dVersion );
00087 else
00088 sprintf( str, "(init %s (version %f))", strTeamName, dVersion );
00089 ACT->sendMessage( str );
00090 }
00091
00096 void Player::mainLoop( )
00097 {
00098 while( bContLoop )
00099 {
00100 Log.logWithTime( 3, " start update_all" );
00101 Log.setHeader( WM->getCurrentCycle(), WM->getPlayerNumber() );
00102
00103 if( WM->updateAll( ) == true )
00104 {
00105 if( shallISaySomething() == true )
00106 {
00107 m_timeLastSay = WM->getCurrentTime();
00108 ACT->sendCommandDirect( sayBallStatus() );
00109 }
00110
00111 switch( formations->getPlayerType( ) )
00112 {
00113 case PT_GOALKEEPER: goalieMainLoop( ); break;
00114 case PT_DEFENDER_SWEEPER:
00115 case PT_DEFENDER_WING: defenderMainLoop( ); break;
00116 case PT_MIDFIELDER_CENTER:
00117 case PT_MIDFIELDER_WING: midfielderMainLoop( ); break;
00118 case PT_ATTACKER:
00119 case PT_ATTACKER_WING: attackerMainLoop( ); break;
00120 case PT_ILLEGAL:
00121 default: break;
00122 }
00123
00124 Log.logWithTime( 3, " determined action; waiting for new info" );
00125
00126
00127 if( WM->getTimeLastSeeMessage() == WM->getCurrentTime() )
00128 ACT->sendCommands( );
00129 }
00130 else
00131 Log.logWithTime( 3, " HOLE no action determined; waiting for new info" );
00132
00133
00134
00135 if( WM->waitForNewInformation() == false )
00136 bContLoop = false;
00137 }
00138
00139
00140 printf("Shutting down player %d\n", WM->getPlayerNumber() );
00141 printf(" Number of holes: %d (%f)\n", WM->iNrHoles,
00142 ((double)WM->iNrHoles/WM->getCurrentCycle())*100 );
00143 printf(" Teammates seen: %d (%f)\n", WM->iNrTeammatesSeen,
00144 ((double)WM->iNrTeammatesSeen/WM->getCurrentCycle()) );
00145 printf(" Opponents seen: %d (%f)\n", WM->iNrOpponentsSeen,
00146 ((double)WM->iNrOpponentsSeen/WM->getCurrentCycle()) );
00147
00148 }
00149
00151 void Player::goalieMainLoop( )
00152 {
00153 deMeer5_goalie();
00154 }
00155
00157 void Player::defenderMainLoop( )
00158 {
00159 deMeer5() ;
00160 }
00161
00163 void Player::midfielderMainLoop( )
00164 {
00165 deMeer5() ;
00166 }
00167
00169 void Player::attackerMainLoop( )
00170 {
00171 deMeer5();
00172 }
00173
00184 void Player::deMeer5( )
00185 {
00186
00187 SoccerCommand soc(CMD_ILLEGAL);
00188 VecPosition posAgent = WM->getAgentGlobalPosition();
00189 VecPosition posBall = WM->getBallPos();
00190 int iTmp;
00191
00192 if( WM->isKickOffThem( ) )
00193 ;
00194 else if( WM->isBeforeKickOff( ) )
00195 {
00196 if( formations->getFormation() != FT_INITIAL )
00197 formations->setFormation( FT_INITIAL );
00198 VecPosition posStrat = WM->getStrategicPosition();
00199 if( WM->isKickOffThem( ) && posStrat.getDistanceTo( VecPosition(0,0) ) < 9.0 )
00200 posStrat.setX( -10.0 );
00201
00202 if( posAgent.getDistanceTo( posStrat ) > 2.0 )
00203 ACT->putCommandInQueue( teleportToPos( posStrat ) );
00204 else
00205 {
00206 ACT->putCommandInQueue( turnBodyToPoint( VecPosition( 0, 0 ), 0 ) );
00207 ACT->putCommandInQueue( alignNeckWithBody( ) );
00208 }
00209 }
00210 else
00211 {
00212 formations->setFormation( FT_433_OFFENSIVE );
00213 soc.commandType = CMD_ILLEGAL;
00214
00215 if( WM->getConfidence( OBJECT_BALL ) < PS->getBallConfThr() )
00216 {
00217 ACT->putCommandInQueue( searchBall() );
00218 ACT->putCommandInQueue( alignNeckWithBody( ) );
00219 }
00220 else if( WM->isBallKickable())
00221 {
00222 VecPosition posGoal( PITCH_LENGTH/2.0,
00223 (-1 + 2*(WM->getCurrentCycle()%2)) * 0.4 * SS->getGoalWidth() );
00224 soc = kickTo( posGoal, SS->getBallSpeedMax() );
00225
00226 ACT->putCommandInQueue( soc );
00227 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00228 Log.log( 100, "kick ball" );
00229 }
00230 else if( WM->getFastestInSetTo( OBJECT_SET_TEAMMATES, OBJECT_BALL, &iTmp )
00231 == WM->getAgentObjectType() && !WM->isDeadBallThem() )
00232 {
00233 Log.log( 100, "I am fastest to ball; can get there in %d cycles", iTmp );
00234 soc = intercept( false );
00235
00236 if( soc.commandType == CMD_DASH &&
00237 WM->getAgentStamina().getStamina() <
00238 SS->getRecoverDecThr()*SS->getStaminaMax()+200 )
00239 {
00240 soc.dPower = 30.0 * WM->getAgentStamina().getRecovery();
00241 ACT->putCommandInQueue( soc );
00242 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00243 }
00244 else
00245 {
00246 ACT->putCommandInQueue( soc );
00247 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00248 }
00249 }
00250 else if( posAgent.getDistanceTo(WM->getStrategicPosition()) >
00251 1.5 + fabs(posAgent.getX()-posBall.getX())/10.0)
00252
00253 {
00254 if( WM->getAgentStamina().getStamina() >
00255 SS->getRecoverDecThr()*SS->getStaminaMax()+200 )
00256 {
00257 soc = moveToPos(WM->getStrategicPosition(),PS->getPlayerWhenToTurnAngle());
00258 ACT->putCommandInQueue( soc );
00259 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00260 }
00261 else
00262 {
00263 ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) );
00264 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00265 }
00266 }
00267 else if( fabs( WM->getRelativeAngle( OBJECT_BALL ) ) > 1.0 )
00268 {
00269 ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) );
00270 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00271 }
00272 else
00273 ACT->putCommandInQueue( SoccerCommand(CMD_TURNNECK,0.0) );
00274 }
00275 }
00276
00277
00284 void Player::deMeer5_goalie( )
00285 {
00286 int i;
00287 SoccerCommand soc;
00288 VecPosition posAgent = WM->getAgentGlobalPosition();
00289 AngDeg angBody = WM->getAgentGlobalBodyAngle();
00290
00291
00292 static const VecPosition posLeftTop( -PITCH_LENGTH/2.0 +
00293 0.7*PENALTY_AREA_LENGTH, -PENALTY_AREA_WIDTH/4.0 );
00294 static const VecPosition posRightTop( -PITCH_LENGTH/2.0 +
00295 0.7*PENALTY_AREA_LENGTH, +PENALTY_AREA_WIDTH/4.0 );
00296
00297
00298 static Line lineFront = Line::makeLineFromTwoPoints(posLeftTop, posRightTop);
00299 static Line lineLeft = Line::makeLineFromTwoPoints(
00300 VecPosition( -50.0, posLeftTop.getY()), posLeftTop );
00301 static Line lineRight = Line::makeLineFromTwoPoints(
00302 VecPosition( -50.0, posRightTop.getY()),posRightTop );
00303
00304
00305 if( WM->isBeforeKickOff( ) )
00306 {
00307 if( formations->getFormation() != FT_INITIAL ||
00308 posAgent.getDistanceTo( WM->getStrategicPosition() ) > 2.0 )
00309 {
00310 formations->setFormation( FT_INITIAL );
00311 ACT->putCommandInQueue( teleportToPos( WM->getStrategicPosition() ) );
00312 }
00313 else
00314 {
00315 ACT->putCommandInQueue( turnBodyToPoint( VecPosition( 0, 0 ), 0 ) );
00316 ACT->putCommandInQueue( alignNeckWithBody( ) );
00317 }
00318 return;
00319 }
00320
00321 if( WM->getConfidence( OBJECT_BALL ) < PS->getBallConfThr() )
00322 {
00323 ACT->putCommandInQueue( searchBall() );
00324 ACT->putCommandInQueue( alignNeckWithBody( ) );
00325 }
00326 else if( WM->getPlayMode() == PM_PLAY_ON || WM->isFreeKickThem() ||
00327 WM->isCornerKickThem() )
00328 {
00329 if( WM->isBallCatchable() )
00330 {
00331 ACT->putCommandInQueue( soc = catchBall() );
00332 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00333 }
00334 else if( WM->isBallKickable() )
00335 {
00336 soc = kickTo( VecPosition(0,posAgent.getY()*2.0), 2.0 );
00337 ACT->putCommandInQueue( soc );
00338 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00339 }
00340 else if( WM->isInOwnPenaltyArea( getInterceptionPointBall( &i, true ) ) &&
00341 WM->getFastestInSetTo( OBJECT_SET_PLAYERS, OBJECT_BALL, &i ) ==
00342 WM->getAgentObjectType() )
00343 {
00344 ACT->putCommandInQueue( soc = intercept( true ) );
00345 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00346 }
00347 else
00348 {
00349
00350 VecPosition posMyGoal = ( WM->getSide() == SIDE_LEFT )
00351 ? SoccerTypes::getGlobalPositionFlag(OBJECT_GOAL_L, SIDE_LEFT )
00352 : SoccerTypes::getGlobalPositionFlag(OBJECT_GOAL_R, SIDE_RIGHT);
00353 Line lineBall = Line::makeLineFromTwoPoints( WM->getBallPos(), posMyGoal);
00354
00355
00356 VecPosition posIntersect = lineFront.getIntersection( lineBall );
00357
00358
00359 if (posIntersect.isRightOf( posRightTop ) )
00360 posIntersect = lineRight.getIntersection( lineBall );
00361 else if (posIntersect.isLeftOf( posLeftTop ) )
00362 posIntersect = lineLeft.getIntersection( lineBall );
00363
00364 if( posIntersect.getX() < -49.0 )
00365 posIntersect.setX( -49.0 );
00366
00367
00368 if( posIntersect.getDistanceTo( WM->getAgentGlobalPosition() ) > 0.5 )
00369 {
00370 soc = moveToPos( posIntersect, PS->getPlayerWhenToTurnAngle() );
00371 ACT->putCommandInQueue( soc );
00372 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00373 }
00374 else
00375 {
00376 ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) );
00377 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00378 }
00379 }
00380 }
00381 else if( WM->isFreeKickUs() == true || WM->isGoalKickUs() == true )
00382 {
00383 if( WM->isBallKickable() )
00384 {
00385 if( WM->getTimeSinceLastCatch() == 25 && WM->isFreeKickUs() )
00386 {
00387
00388 if( WM->getNrInSetInCircle( OBJECT_SET_OPPONENTS,
00389 Circle(posRightTop, 15.0 )) <
00390 WM->getNrInSetInCircle( OBJECT_SET_OPPONENTS,
00391 Circle(posLeftTop, 15.0 )) )
00392 soc.makeCommand( CMD_MOVE, posRightTop.getX(),posRightTop.getY(),0.0);
00393 else
00394 soc.makeCommand( CMD_MOVE, posLeftTop.getX(), posLeftTop.getY(), 0.0);
00395 ACT->putCommandInQueue( soc );
00396 }
00397 else if( WM->getTimeSinceLastCatch() > 28 )
00398 {
00399 soc = kickTo( VecPosition(0,posAgent.getY()*2.0), 2.0 );
00400 ACT->putCommandInQueue( soc );
00401 }
00402 else if( WM->getTimeSinceLastCatch() < 25 )
00403 {
00404 VecPosition posSide( 0.0, posAgent.getY() );
00405 if( fabs( (posSide - posAgent).getDirection() - angBody) > 10 )
00406 {
00407 soc = turnBodyToPoint( posSide );
00408 ACT->putCommandInQueue( soc );
00409 }
00410 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00411 }
00412 }
00413 else if( WM->isGoalKickUs() )
00414 {
00415 ACT->putCommandInQueue( soc = intercept( true ) );
00416 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00417 }
00418 else
00419 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00420 }
00421 else
00422 {
00423 ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) );
00424 ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) );
00425 }
00426
00427 }
00428
00431 bool Player::shallISaySomething( )
00432 {
00433 bool bReturn;
00434
00435 bReturn = ((WM->getCurrentTime() - m_timeLastSay) >= SS->getHearDecay());
00436 bReturn &= amIAgentToSaySomething();
00437 bReturn &= (WM->getCurrentCycle() > 0 );
00438
00439 return bReturn;
00440 }
00441
00445 bool Player::amIAgentToSaySomething()
00446 {
00447
00448 if( WM->getTimeChangeInformation(OBJECT_BALL) == WM->getCurrentTime() ||
00449 WM->getRelativeDistance( OBJECT_BALL ) < SS->getVisibleDistance() )
00450 return true;
00451
00452 return false;
00453 }
00454
00457 SoccerCommand Player::sayBallStatus( )
00458 {
00459 char strMsg[MAX_SAY_MSG];
00460
00461
00462
00463 VecPosition posBall = WM->getGlobalPosition( OBJECT_BALL );
00464 VecPosition velBall = WM->getGlobalVelocity( OBJECT_BALL );
00465 double x = min( posBall.getX() + 52.5, 99.9);
00466 sprintf( strMsg, "%c%c%c%c%c%c%c%c",
00467 '0' + ((int)( x ) % 100 ) / 10 ,
00468 '0' + ((int)( x ) % 100 ) % 10 ,
00469 '0' + ((int)( posBall.getY() + 34.0) % 100 ) / 10 ,
00470 '0' + ((int)( posBall.getY() + 34.0) % 100 ) % 10 ,
00471 '0' + ((int)(( velBall.getX() + 2.7) * 10 )) / 10 ,
00472 '0' + ((int)(( velBall.getX() + 2.7) * 10 )) % 10 ,
00473 '0' + ((int)(( velBall.getY() + 2.7) * 10 )) / 10 ,
00474 '0' + ((int)(( velBall.getY() + 2.7) * 10 )) % 10 );
00475
00476 return communicate( strMsg );
00477 }
00478
00479
00484 void Player::test_only_update()
00485 {
00486 while( bContLoop )
00487 {
00488 WM->updateAll();
00489 if( WM->waitForNewInformation() == false )
00490 {
00491 printf("Server dead; exiting" );
00492 bContLoop = false;
00493 }
00494 }
00495 }
00496
00506 void* stdin_callback( void * v )
00507 {
00508 Log.log( 1, "Starting to listen for user input" );
00509 Player* p = (Player*)v;
00510 p->handleStdin();
00511 return NULL;
00512 }
00513
00525 void Player::handleStdin( )
00526 {
00527 char buf[MAX_MSG];
00528
00529 while( bContLoop )
00530 {
00531 fgets( buf, MAX_MSG, stdin );
00532 printf( "after fgets: %s\n", buf );
00533 executeStringCommand( buf );
00534 }
00535 }
00536
00542 void Player::showStringCommands( ostream& out )
00543 {
00544 out << "Basic commands:" << endl <<
00545 " a(ctions)" << endl <<
00546 " c(atch) direction" << endl <<
00547 " cs(lientsettings" << endl <<
00548 " d(ash) power [ times ]" << endl <<
00549 " de(bug) nr_cycles" << endl <<
00550 " g(oto) x y" << endl <<
00551 " h(elp)" << endl <<
00552 " i(ntercept) x y" << endl <<
00553 " k(ick) power angle" << endl <<
00554 " ka x y endspeed " << endl <<
00555 " m(ove) x y" << endl <<
00556 " n(eck) angle" << endl <<
00557 " o(pponents in cone) width dist" << endl <<
00558 " p(redict cycles to) x y" << endl <<
00559 " q(uit)" << endl <<
00560 " s(ay) message" << endl <<
00561 " ss(erversettings)" << endl <<
00562 " t(urn) angle" << endl <<
00563 " v(iewmode) narrow | normal | wide low | high" << endl <<
00564 " w(orldmodel)" << endl;
00565 }
00566
00571 bool Player::executeStringCommand( char *str)
00572 {
00573 SoccerCommand socCommand;
00574 int i;
00575 double x, y;
00576
00577 switch( str[0] )
00578 {
00579 case 'a':
00580 WM->showQueuedCommands();
00581 break;
00582 case 'c':
00583 if( strlen(str) > 1 && str[1] == 's' )
00584 {
00585 PS->show( cout, ":" );
00586 break;
00587 }
00588 socCommand.makeCommand( CMD_CATCH, Parse::parseFirstInt( &str ) );
00589 break;
00590 case 'd':
00591 socCommand.commandType = CMD_DASH;
00592 socCommand.dPower = Parse::parseFirstDouble( &str );
00593 socCommand.iTimes = Parse::parseFirstInt ( &str );
00594 if( socCommand.iTimes == 0 ) socCommand.iTimes = 1;
00595 break;
00596 case 'h':
00597 showStringCommands( cout );
00598 return true;
00599 case 'k':
00600 socCommand.commandType = CMD_KICK;
00601 if( str[1] == 'a' )
00602 {
00603 double x = Parse::parseFirstDouble( &str );
00604 double y = Parse::parseFirstDouble( &str );
00605 double e = Parse::parseFirstDouble( &str );
00606 socCommand = kickTo( VecPosition( x, y), e );
00607 }
00608 else
00609 {
00610 socCommand.dPower = Parse::parseFirstDouble( &str );
00611 socCommand.dAngle = Parse::parseFirstDouble( &str );
00612 }
00613 break;
00614 case 'm':
00615 socCommand.commandType = CMD_MOVE;
00616 socCommand.dX = Parse::parseFirstDouble( &str );
00617 socCommand.dY = Parse::parseFirstDouble( &str );
00618 socCommand.dAngle = Parse::parseFirstDouble( &str );
00619 break;
00620 case 'n':
00621 socCommand.commandType = CMD_TURNNECK;
00622 socCommand.dAngle = Parse::parseFirstDouble( &str );
00623 break;
00624 case 'o':
00625 x = Parse::parseFirstDouble( &str );
00626 y = Parse::parseFirstDouble( &str );
00627 i = WM->getNrInSetInCone( OBJECT_SET_OPPONENTS, x, WM->getAgentGlobalPosition(),
00628 WM->getAgentGlobalPosition()+VecPosition( y,
00629 WM->getAgentGlobalNeckAngle(), POLAR ) );
00630 printf( "%d opponents\n", i );
00631 return true;
00632 case 'p':
00633 x = Parse::parseFirstDouble( &str );
00634 y = Parse::parseFirstDouble( &str );
00635 i = WM->predictNrCyclesToPoint( WM->getAgentObjectType(),
00636 VecPosition( x, y ), PS->getPlayerWhenToTurnAngle() );
00637 printf( "%d cycles\n", i );
00638 return true;
00639 case 'q':
00640 bContLoop = false;
00641 return true;
00642 case 's':
00643 if( strlen(str) > 1 && str[1] == 's' )
00644 {
00645 SS->show( cout, ":" );
00646 break;
00647 }
00648 socCommand.commandType = CMD_SAY;
00649 Parse::gotoFirstOccurenceOf( ' ', &str );
00650 Parse::gotoFirstNonSpace( &str );
00651 strcpy( socCommand.str, str);
00652 break;
00653 case 't':
00654 socCommand.commandType = CMD_TURN;
00655 socCommand.dAngle = Parse::parseFirstDouble( &str );
00656 break;
00657 case 'v':
00658 socCommand.commandType = CMD_CHANGEVIEW;
00659 Parse::gotoFirstOccurenceOf(' ', &str );
00660 Parse::gotoFirstNonSpace( &str );
00661 socCommand.va = SoccerTypes::getViewAngleFromStr( str );
00662 Parse::gotoFirstOccurenceOf(' ', &str );
00663 Parse::gotoFirstNonSpace( &str );
00664 socCommand.vq = SoccerTypes::getViewQualityFromStr( str );
00665 break;
00666 case 'w':
00667 WM->show();
00668 return true;
00669 default:
00670 ACT->sendMessage( str );
00671 return true;
00672 }
00673 if( socCommand.commandType != CMD_ILLEGAL )
00674 ACT->putCommandInQueue( socCommand );
00675
00676 return true;
00677 }