📄 player.cpp
字号:
/*! This is the main decision loop for a defender. */
SoccerCommand Player::defenderMainLoop( )
{
return deMeer5() ;
}
/*! This is the main decision loop for a midfielder. */
SoccerCommand Player::midfielderMainLoop( )
{
return deMeer5() ;
}
/*! This is the main decision loop for an agent. */
SoccerCommand Player::attackerMainLoop( )
{
return deMeer5() ;
}
/*! This method returns the position to move in case of a dead ball situation.
A dead ball situation occurs when the team can have a free kick, kick in,
etc. The agent will move to the position behind the ball and when he is
there will move to the ball again. */
VecPosition Player::getDeadBallPosition( )
{
VecPosition pos, posBall = WM->getBallPos();
VecPosition posAgent = WM->getAgentGlobalPosition();
double dDist;
// determine point to move to
if( WM->isKickInUs() )
pos = posBall + VecPosition( -1.5, sign( posBall.getY() )*1.5 );
else if( WM->isCornerKickUs( ) )
pos = posBall + VecPosition( 1.5, sign( posBall.getY() ) * 1.5 );
else if( WM->isFreeKickUs() || WM->isOffsideThem() || WM->isGoalKickUs() ||
WM->isFreeKickFaultThem() || WM->isBackPassThem() )
pos = posBall + VecPosition( -1.5, 0.0 );
else
return VecPosition( UnknownDoubleValue, UnknownDoubleValue );
AngDeg angBall = (posBall-posAgent).getDirection() ;
ObjectT obj = WM->getClosestInSetTo( OBJECT_SET_PLAYERS,
WM->getAgentObjectType(), &dDist);
VecPosition posPlayer = WM->getGlobalPosition( obj );
// change point when heading towards other player or towards the ball
if( fabs( angBall - (posPlayer-posAgent).getDirection() ) < 20 &&
dDist < 6 )
pos -= VecPosition( 5, 0 );
if( fabs( angBall - (pos-posAgent).getDirection()) < 20 )
{
angBall = VecPosition::normalizeAngle( angBall - 90 );
pos = posBall + VecPosition( 1, angBall , POLAR );
}
return pos;
}
/*!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 )
{
#ifdef WIN32
cin.getline( buf, MAX_MSG );
#else
fgets( buf, MAX_MSG, stdin ); // does unblock with signal !!!!!
#endif
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 ) );
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 WIN32
DWORD WINAPI stdin_callback( LPVOID v )
#else
void* stdin_callback( void * v )
#endif
{
Log.log( 1, "Starting to listen for user input" );
Player* p = (Player*)v;
p->handleStdin();
#ifdef WIN32
return 0;
#else
return NULL;
#endif
}
/********************** 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() &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -