📄 player.c
字号:
else if( WM->isInOwnPenaltyArea( getInterceptionPointBall( &i, true ) ) && WM->getFastestInSetTo( OBJECT_SET_PLAYERS, OBJECT_BALL, &i ) == WM->getAgentObjectType() ) { ACT->putCommandInQueue( soc = intercept( true ) ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } else { // make line between own goal and the ball VecPosition posMyGoal = ( WM->getSide() == SIDE_LEFT ) ? SoccerTypes::getGlobalPositionFlag(OBJECT_GOAL_L, SIDE_LEFT ) : SoccerTypes::getGlobalPositionFlag(OBJECT_GOAL_R, SIDE_RIGHT); Line lineBall = Line::makeLineFromTwoPoints( WM->getBallPos(), posMyGoal); // determine where your front line intersects with the line from ball VecPosition posIntersect = lineFront.getIntersection( lineBall ); // outside rectangle, use line at side to get intersection if (posIntersect.isRightOf( posRightTop ) ) posIntersect = lineRight.getIntersection( lineBall ); else if (posIntersect.isLeftOf( posLeftTop ) ) posIntersect = lineLeft.getIntersection( lineBall ); if( posIntersect.getX() < -49.0 ) posIntersect.setX( -49.0 ); // and move to this position if( posIntersect.getDistanceTo( WM->getAgentGlobalPosition() ) > 0.5 ) { soc = moveToPos( posIntersect, PS->getPlayerWhenToTurnAngle() ); ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } else { ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } } } else if( WM->isFreeKickUs() == true || WM->isGoalKickUs() == true ) { if( WM->isBallKickable() ) { if( WM->getTimeSinceLastCatch() == 25 && WM->isFreeKickUs() ) { // move to position with lesser opponents. if( WM->getNrInSetInCircle( OBJECT_SET_OPPONENTS, Circle(posRightTop, 15.0 )) < WM->getNrInSetInCircle( OBJECT_SET_OPPONENTS, Circle(posLeftTop, 15.0 )) ) soc.makeCommand( CMD_MOVE, posRightTop.getX(),posRightTop.getY(),0.0); else soc.makeCommand( CMD_MOVE, posLeftTop.getX(), posLeftTop.getY(), 0.0); ACT->putCommandInQueue( soc ); } else if( WM->getTimeSinceLastCatch() > 28 ) { soc = kickTo( VecPosition(0,posAgent.getY()*2.0), 2.0 ); ACT->putCommandInQueue( soc ); } else if( WM->getTimeSinceLastCatch() < 25 ) { VecPosition posSide( 0.0, posAgent.getY() ); if( fabs( (posSide - posAgent).getDirection() - angBody) > 10 ) { soc = turnBodyToPoint( posSide ); ACT->putCommandInQueue( soc ); } ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } } else if( WM->isGoalKickUs() ) { ACT->putCommandInQueue( soc = intercept( true ) ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } else ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } else { ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); }}/*!This method determines whether a player should say something. \return bool indicating whether the agent should say a message */bool Player::shallISaySomething( ){ bool bReturn; bReturn = ((WM->getCurrentTime() - m_timeLastSay) >= SS->getHearDecay()); bReturn &= amIAgentToSaySomething(); 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(){ // if got good information of the ball, communicate. if( WM->getTimeChangeInformation(OBJECT_BALL) == WM->getCurrentTime() || WM->getRelativeDistance( OBJECT_BALL ) < SS->getVisibleDistance() ) return true; return false;}/*! This method is used to communicate the status of the ball, that is its position and velocity.*/SoccerCommand Player::sayBallStatus( ){ char strMsg[MAX_SAY_MSG]; // 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 VecPosition posBall = WM->getGlobalPosition( OBJECT_BALL ); VecPosition velBall = WM->getGlobalVelocity( OBJECT_BALL ); double x = min( posBall.getX() + 52.5, 99.9); sprintf( strMsg, "%c%c%c%c%c%c%c%c", '0' + ((int)( x ) % 100 ) / 10 , '0' + ((int)( x ) % 100 ) % 10 , '0' + ((int)( posBall.getY() + 34.0) % 100 ) / 10 , '0' + ((int)( 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 ); return communicate( strMsg );}/*!This method does nothing except updating the worldmodel after each arrival of a see or sense_body message. Using this test program it is possible to control the commands of the agent using the standard input and see the resulting behavior of the agent. */void Player::test_only_update(){ while( bContLoop ) { WM->updateAll(); if( WM->waitForNewInformation() == false ) { printf("Server dead; exiting" ); bContLoop = false; } }}/*!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*/void* stdin_callback( void * v ){ Log.log( 1, "Starting to listen for user input" ); Player* p = (Player*)v; p->handleStdin(); return NULL;}/*!This method listens for input from the keyboard and when it receives this input it converts this input to the associated action. See showStringCommands for the possible options. This method is used together with the SenseHandler class that sends an alarm to indicate that a new command can be sent. This conflicts with the method in this method that listens for the user input (fgets) on Linux systems (on Solaris this isn't a problem). The only known method is to use the flag SA_RESTART with this alarm function, but that does not seem to work under Linux. If each time the alarm is sent, this gets function unblocks, it will cause major performance problems. This function should not be called when a whole match is played! */void Player::handleStdin( ){ char buf[MAX_MSG]; while( bContLoop ) { fgets( buf, MAX_MSG, stdin ); // does unblock with signal !!!!! printf( "after fgets: %s\n", buf ); executeStringCommand( buf ); }}/*!This method prints the possible commands that can be entered by the user. The whole name can be entered to perform the corresponding command, but normally only the first character is sufficient. This is indicated by putting brackets around the part of the command that is not needed. \param out output stream to which the possible commands are printed */void Player::showStringCommands( ostream& out ){ out << "Basic commands:" << endl << " a(ctions)" << endl << " c(atch) direction" << endl << " cs(lientsettings" << endl << " d(ash) power [ times ]" << endl << " de(bug) nr_cycles" << endl << " g(oto) x y" << endl << " h(elp)" << endl << " i(ntercept) x y" << endl << " k(ick) power angle" << endl << " ka x y endspeed " << endl << " m(ove) x y" << endl << " n(eck) angle" << endl << " o(pponents in cone) width dist" << endl << " p(redict cycles to) x y" << endl << " q(uit)" << endl << " s(ay) message" << endl << " ss(erversettings)" << endl << " t(urn) angle" << endl << " v(iewmode) narrow | normal | wide low | high" << endl << " w(orldmodel)" << endl;}/*!This method executes the command that is entered by the user. For the possible command look at the method showStringCommands. \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 ), PS->getPlayerWhenToTurnAngle() ); 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -