📄 player.cpp.svn-base
字号:
\param str string that is entered by the user \return true when command could be executed, false otherwise */bool Player::executeStringCommand( char *str){/* SoccerCommand socCommand; int i; double x, y; switch( str[0] ) { case 'a': // actions WM->showQueuedCommands(); break; case 'c': // catch dir or cs if( strlen(str) > 1 && str[1] == 's' ) { PS->show( cout, ":" ); break; } socCommand.makeCommand( CMD_CATCH, Parse::parseFirstInt( &str ) ); break; case 'd': // dash socCommand.commandType = CMD_DASH; socCommand.dPower = Parse::parseFirstDouble( &str ); socCommand.iTimes = Parse::parseFirstInt ( &str ); if( socCommand.iTimes == 0 ) socCommand.iTimes = 1; break; case 'h': // help showStringCommands( cout ); return true; case 'k': // kick or ka (kick advanced) socCommand.commandType = CMD_KICK; if( str[1] == 'a' ) // advanced kick { double x = Parse::parseFirstDouble( &str ); double y = Parse::parseFirstDouble( &str ); double e = Parse::parseFirstDouble( &str ); socCommand = kickTo( VecPosition( x, y), e ); } else { socCommand.dPower = Parse::parseFirstDouble( &str ); socCommand.dAngle = Parse::parseFirstDouble( &str ); } break; case 'm': // move socCommand.commandType = CMD_MOVE; socCommand.dX = Parse::parseFirstDouble( &str ); socCommand.dY = Parse::parseFirstDouble( &str ); socCommand.dAngle = Parse::parseFirstDouble( &str ); break; case 'n': // turn_neck socCommand.commandType = CMD_TURNNECK; socCommand.dAngle = Parse::parseFirstDouble( &str ); break; case 'o': // count nr opp in cone x = Parse::parseFirstDouble( &str ); y = Parse::parseFirstDouble( &str ); i = WM->getNrInSetInCone( OBJECT_SET_OPPONENTS, x, WM->getAgentGlobalPosition(), WM->getAgentGlobalPosition() + VecPosition( y, WM->getAgentGlobalNeckAngle(), POLAR ) ); printf( "%d opponents\n", i ); return true; case 'p': // predict cycles to point x = Parse::parseFirstDouble( &str ); y = Parse::parseFirstDouble( &str ); i = WM->predictNrCyclesToPoint( WM->getAgentObjectType(), VecPosition( x, y ) ); printf( "%d cycles\n", i ); return true; case 'q': // quit bContLoop = false; return true; case 's': // ss (serversettings) or say if( strlen(str) > 1 && str[1] == 's' ) { SS->show( cout, ":" ); break; } socCommand.commandType = CMD_SAY; Parse::gotoFirstOccurenceOf( ' ', &str ); Parse::gotoFirstNonSpace( &str ); strcpy( socCommand.str, str); break; case 't': // turn socCommand.commandType = CMD_TURN; socCommand.dAngle = Parse::parseFirstDouble( &str ); break; case 'v': // change_view socCommand.commandType = CMD_CHANGEVIEW; Parse::gotoFirstOccurenceOf(' ', &str ); Parse::gotoFirstNonSpace( &str ); socCommand.va = SoccerTypes::getViewAngleFromStr( str ); Parse::gotoFirstOccurenceOf(' ', &str ); Parse::gotoFirstNonSpace( &str ); socCommand.vq = SoccerTypes::getViewQualityFromStr( str ); break; case 'w': // worldmodel WM->show(); return true; default: // default: send entered string ACT->sendMessage( str ); return true; } if( socCommand.commandType != CMD_ILLEGAL ) // when socCommand is set ACT->putCommandInQueue( socCommand ); // send it.*/ return true;}/*!This method can be called in a separate thread (see pthread_create) since it returns a void pointer. It is assumed that this function receives a BasicPlayer class as argument. The only thing this function does is starting the method handleStdin() from the corresponding BasicPlayer class that listens to user input from the keyboard. This function is necessary since a method from a class cannot be an argument of pthread_create. \param v void pointer to a BasicPlayer class. \return should never return since function handleStdin has infinite loop*/#ifdef WIN32DWORD WINAPI stdin_callback( LPVOID v )#elsevoid* stdin_callback( void * v )#endif{ Log.log( 1, "Starting to listen for user input" ); Player* p = (Player*)v; p->handleStdin(); return NULL;}/********************** SAY **************************************************//*This method determines whether a player should say something. \return bool indicating whether the agent should say a message bool Player::shallISaySomething( SoccerCommand socPri ){ bool bReturn; bReturn = ((WM->getCurrentTime() - m_timeLastSay) >= SS->getHearDecay()); bReturn &= amIAgentToSaySomething( socPri ); bReturn &= (WM->getCurrentCycle() > 0 ); return bReturn;}/*! This method returns a boolean indicating whether I should communicate my world model to the other agents. \return boolean indicating whether I should communicate my world model. *bool Player::amIAgentToSaySomething( SoccerCommand socPri ){ double dDist; ObjectT obj; // get the closest teammate to the ball, if we are not him, we do not // communicate since he will obj = WM->getClosestInSetTo( OBJECT_SET_TEAMMATES,OBJECT_BALL,&dDist); if( dDist < SS->getVisibleDistance() && obj != WM->getAgentObjectType() ) return false; // in the defense, player 6 keeps track of the opponent attacker if( WM->getBallPos().getX() < - PENALTY_X + 4.0 && WM->getConfidence( OBJECT_BALL ) > 0.96 && WM->getPlayerNumber() == 6 && WM->getCurrentCycle() % 3 == 0 ) // once very 3 cycles is enough { Log.log( 600, "player 6 is going to communicate attacker info" ); return true; } VecPosition posBallPred; WM->predictBallInfoAfterCommand( socPri, &posBallPred ); VecPosition posAgentPred = WM->predictAgentPosAfterCommand( socPri ); // in all other cases inform teammates of ball when you have good information if( ( WM->getTimeChangeInformation(OBJECT_BALL) == WM->getCurrentTime() && WM->getRelativeDistance( OBJECT_BALL ) < 20.0 && WM->getTimeLastSeen( OBJECT_BALL ) == WM->getCurrentTime() ) || ( WM->getRelativeDistance( OBJECT_BALL ) < SS->getVisibleDistance() && WM->getTimeLastSeen( OBJECT_BALL ) == WM->getCurrentTime() ) || ( // pass ball WM->getRelativeDistance( OBJECT_BALL ) < SS->getMaximalKickDist() && posBallPred.getDistanceTo( posAgentPred ) > SS->getMaximalKickDist() ) ) return true; return false;}/*! This method encodes the opponent attacker status in a visual message. \return string in which the opponent attacker position is encoded.*void Player::sayOppAttackerStatus( char* strMsg ){ char strTmp[MAX_SAY_MSG]; // fill the first byte with some encoding to indicate the current cycle. // The second byte is the last digit of the cycle added to 'a'. sprintf( strMsg, "%c", 'a' + WM->getCurrentCycle()%10 ); // fill the second byte with information about the offside line. // Enter either a value between a-z or A-Z indicating. This gives 52 possible // values which correspond with meters on the field. So B means the offside // line lies at 27.0. int iOffside = (int)WM->getOffsideX(); if( iOffside < 26 ) // 0..25 sprintf( strTmp, "%c", 'a' + iOffside ); else // 26... sprintf( strTmp, "%c", 'A' + max(iOffside - 26, 25) ); strcat( strMsg, strTmp ); // find the closest opponent attacker to the penalty spot. double dDist ; ObjectT objOpp = WM->getClosestInSetTo( OBJECT_SET_OPPONENTS, VecPosition(- PITCH_LENGTH/2.0 + 11.0, 0 ), &dDist ) ; if( objOpp == OBJECT_ILLEGAL || dDist >= 20.0 ) { strncpy( strMsg, "", 0 ); return; } VecPosition posOpp = WM->getGlobalPosition( objOpp ); if( fabs( posOpp.getY() ) > 10 ) { strncpy( strMsg, "", 0 ); return; } // encode the position of this attacker in the visual message. The // player_number is the third byte, then comes the x position in 3 digits (it // is assumed this value is always negative), a space and finally the y // position in 2 digits. An example of opponent nr. 9 at position // (-40.3223,-3.332) is "j403 -33) sprintf( strTmp, "%c%d %d", 'a' + SoccerTypes::getIndex( objOpp ) , (int)(fabs(posOpp.getX())*10), (int)(posOpp.getY()*10)); strcat( strMsg, strTmp ); return ;}/*! This method creates a string to communicate the ball status. When the player just kicks the ball, it is the new velocity of the ball, otherwise it is the current velocity. \param strMsg will be filled *void Player::sayBallStatus( char * strMsg ){ VecPosition posBall = WM->getGlobalPosition( OBJECT_BALL ); VecPosition velBall = WM->getGlobalVelocity( OBJECT_BALL ); int iDiff = 0; SoccerCommand soc = ACT->getPrimaryCommand(); if( WM->getRelativeDistance( OBJECT_BALL ) < SS->getMaximalKickDist() ) { // if kick and a pass if( soc.commandType == CMD_KICK ) { WM->predictBallInfoAfterCommand( soc, &posBall, &velBall ); VecPosition posAgent = WM->predictAgentPos( 1, 0 ); if( posBall.getDistanceTo( posAgent ) > SS->getMaximalKickDist() + 0.2 ) iDiff = 1; } if( iDiff == 0 ) { posBall = WM->getGlobalPosition( OBJECT_BALL ); velBall.setVecPosition( 0, 0 ); } } Log.log( 600, "create comm. ball after: (%1.2f,%1.2f)(%1.2f,%1.2f) diff %d", posBall.getX(), posBall.getY(), velBall.getX(), velBall.getY(), iDiff); makeBallInfo( posBall, velBall, iDiff, strMsg );}/*! This method is used to create the communicate message for the status of the ball, that is its position and velocity is encoded. \param VecPosition posBall ball position \param VecPosition velBall ball velocity \param iDiff time difference corresponding to given ball information \strMsg string message in which the ball information is encoded. *void Player::makeBallInfo( VecPosition posBall, VecPosition velBall, int iDiff, char * strMsg ){ char strTmp[MAX_SAY_MSG]; // fill the first byte with some encoding to indicate the next cycle. // The second byte is the last digit of the cycle added to 'a'. sprintf( strMsg, "%c", 'a' + (WM->getCurrentCycle()+iDiff)%10 ); // fill the second byte with information about the offside line. // Enter either a value between a-z or A-Z indicating. This gives 52 possible // values which correspond with meters on the field. So B means the offside // line lies at 27.0. int iOffside = (int)( WM->getOffsideX( false ) - 1.0 ); if( iOffside < 26 ) // 0..25 sprintf( strTmp, "%c", 'a' + max( 0, iOffside) ); else // 26... sprintf( strTmp, "%c", 'A' + min(iOffside - 26, 25) ); strcat( strMsg, strTmp ); // First add al values to a positive interval, since then we don't need // another byte for the minus sign. then take one digit at a time double x = max(0,min( rint( posBall.getX() + 48.0), 99.0)); sprintf( strTmp, "%c%c%c%c%c%c%c%c", '0' + ((int)( x ) % 100 ) / 10 , '0' + ((int)( x ) % 100 ) % 10 , '0' + ((int)( rint(posBall.getY() + 34.0)) % 100 ) / 10 , '0' + ((int)( rint(posBall.getY() + 34.0)) % 100 ) % 10 , '0' + ((int)(( velBall.getX() + 2.7) * 10 )) / 10 , '0' + ((int)(( velBall.getX() + 2.7) * 10 )) % 10 , '0' + ((int)(( velBall.getY() + 2.7) * 10 )) / 10 , '0' + ((int)(( velBall.getY() + 2.7) * 10 )) % 10 ); strcat( strMsg, strTmp ); Log.log( 6560, "say (%d) %s\n", WM->getPlayerNumber() , strMsg ); return ;}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -