Robotcup2D学习记录四
这几天学习的重点我放在了如何修改代码的构思上,我个人想把修改的重点放在进攻球员身上,所以这几天反复看了一下进攻球员的代码,阅读记录如下:
bhv_prepare_set_play_kick
//这里的代码写的很简单,就是踢球前的准备动作
bool
Bhv_PrepareSetPlayKick::execute( PlayerAgent * agent )
{
static int s_rest_wait_cycle = -1;
// not reach the ball side
if ( Bhv_GoToStaticBall( M_ball_place_angle ).execute( agent ) )
{
return true;
}
// reach to ball side
if ( s_rest_wait_cycle < 0 )
{
s_rest_wait_cycle = M_wait_cycle;
}
//设置为当前的cycle
if ( s_rest_wait_cycle == 0 )
{
if ( agent->world().self().stamina() < ServerParam::i().staminaMax() * 0.9
|| agent->world().seeTime() != agent->world().time() )
{
s_rest_wait_cycle = 1;
}
}
if ( s_rest_wait_cycle > 0 )
{
if ( agent->world().gameMode().type() == GameMode::KickOff_ )
{
AngleDeg moment( ServerParam::i().visibleAngle() );
agent->doTurn( moment );
}
else
{
Body_TurnToBall().execute( agent );
}
agent->setNeckAction( new Neck_ScanField() );
s_rest_wait_cycle--;
dlog.addText( Logger::TEAM,
__FILE__": wait. rest cycles=%d",
s_rest_wait_cycle );
return true;
}
s_rest_wait_cycle = -1;
return false;
}
bhv_set_play_free_kick
//球员踢球的动作
bool
Bhv_SetPlayFreeKick::execute( PlayerAgent * agent )
{
dlog.addText( Logger::TEAM,
__FILE__": Bhv_SetPlayFreeKick" );
//---------------------------------------------------
if ( Bhv_SetPlay::is_kicker( agent ) )
{ //可以踢球就踢球
doKick( agent );
}
else
{ //不能踢球的情况下,移动
doMove( agent );
}
return true;
}
/*-------------------------------------------------------------------*/
/*!
*/
void
Bhv_SetPlayFreeKick::doKick( PlayerAgent * agent )
{
dlog.addText( Logger::TEAM,
__FILE__": (doKick)" );
//
// go to the ball position
//
if ( Bhv_GoToStaticBall( 0.0 ).execute( agent ) )
{
return;
}
//
// wait
//
if ( doKickWait( agent ) )
{
return;
}
//
// kick
//
const WorldModel & wm = agent->world();
const double max_ball_speed = wm.self().kickRate() * ServerParam::i().maxPower();
//
// pass
//
if ( Bhv_ChainAction().execute( agent ) )
{
agent->debugClient().addMessage( "FreeKick:Chain" );
agent->setIntention( new IntentionWaitAfterSetPlayKick() );
return;
}
const PlayerObject * nearest_teammate = wm.getTeammateNearestToSelf( 10, false ); // without goalie
if ( nearest_teammate
&& nearest_teammate->distFromSelf() < 20.0
&& ( nearest_teammate->pos().x > -30.0
|| nearest_teammate->distFromSelf() < 10.0 ) )
{
Vector2D target_point = nearest_teammate->inertiaFinalPoint();
target_point.x += 0.5;
//这部分是传球的代码
double ball_move_dist = wm.ball().pos().dist( target_point );
int ball_reach_step
= static_cast< int >( std::ceil( calc_length_geom_series( max_ball_speed,
ball_move_dist,
ServerParam::i().ballDecay() ) ) );
double ball_speed = 0.0;
if ( ball_reach_step > 3 )
{
ball_speed = calc_first_term_geom_series( ball_move_dist,
ServerParam::i().ballDecay(),
ball_reach_step );
}
else
{
ball_speed = calc_first_term_geom_series_last( 1.4,
ball_move_dist,
ServerParam::i().ballDecay() );
ball_reach_step
= static_cast< int >( std::ceil( calc_length_geom_series( ball_speed,
ball_move_dist,
ServerParam::i().ballDecay() ) ) );
}
ball_speed = std::min( ball_speed, max_ball_speed );
//对球的速度进行调整
agent->debugClient().addMessage( "FreeKick:ForcePass%.3f", ball_speed );
agent->debugClient().setTarget( target_point );
dlog.addText( Logger::TEAM,
__FILE__": force pass. target=(%.1f %.1f) speed=%.2f reach_step=%d",
target_point.x, target_point.y,
ball_speed, ball_reach_step );
Body_KickOneStep( target_point, ball_speed ).execute( agent );
agent->setNeckAction( new Neck_ScanField() );
return;
}
}
//
// clear
//
if ( ( wm.ball().angleFromSelf() - wm.self().body() ).abs() > 1.5 )
{
agent->debugClient().addMessage( "FreeKick:Clear:TurnToBall" );
dlog.addText( Logger::TEAM,
__FILE__": clear. turn to ball" );
Body_TurnToBall().execute( agent );
agent->setNeckAction( new Neck_ScanField() );
return;
}
agent->debugClient().addMessage( "FreeKick:Clear" );
dlog.addText( Logger::TEAM,
__FILE__": clear" );
Body_ClearBall().execute( agent );
agent->setNeckAction( new Neck_ScanField() );
}
/*-------------------------------------------------------------------*/
/*!
*/
bool
Bhv_SetPlayFreeKick::doKickWait( PlayerAgent * agent )
{
const WorldModel & wm = agent->world();
dlog.addText( Logger::TEAM,
__FILE__": (doKickWait)" );
const int real_set_play_count
= static_cast< int >( wm.time().cycle() - wm.lastSetPlayStartTime().cycle() );
if ( real_set_play_count >= ServerParam::i().dropBallTime() - 5 )
{
dlog.addText( Logger::TEAM,
__FILE__": (doKickWait) real set play count = %d > drop_time-10, force kick mode",
real_set_play_count );
return false;
}
const Vector2D face_point( 40.0, 0.0 );
const AngleDeg face_angle = ( face_point - wm.self().pos() ).th();
if ( wm.time().stopped() != 0 )
{
Body_TurnToPoint( face_point ).execute( agent );
agent->setNeckAction( new Neck_ScanField() );
return true;
}
//拖延策略
if ( Bhv_SetPlay::is_delaying_tactics_situation( agent ) )
{
agent->debugClient().addMessage( "FreeKick:Delaying" );
dlog.addText( Logger::TEAM,
__FILE__": (doKickWait) delaying" );
Body_TurnToPoint( face_point ).execute( agent );
agent->setNeckAction( new Neck_ScanField() );
return true;
}
//无队友情况下
if ( wm.teammatesFromBall().empty() )
{
agent->debugClient().addMessage( "FreeKick:NoTeammate" );
dlog.addText( Logger::TEAM,
__FILE__": (doKickWait) no teammate" );
Body_TurnToPoint( face_point ).execute( agent );
agent->setNeckAction( new Neck_ScanField() );
return true;
}
//根据playCount进行调整
if ( wm.setplayCount() <= 3 )
{
agent->debugClient().addMessage( "FreeKick:Wait%d", wm.setplayCount() );
Body_TurnToPoint( face_point ).execute( agent );
agent->setNeckAction( new Neck_ScanField() );
return true;
}
if ( wm.setplayCount() >= 15
&& wm.seeTime() == wm.time()
&& wm.self().stamina() > ServerParam::i().staminaMax() * 0.6 )
{
dlog.addText( Logger::TEAM,
__FILE__": (doKickWait) set play count = %d, force kick mode",
wm.setplayCount() );
return false;
}
if ( ( face_angle - wm.self().body() ).abs() > 5.0 )
{
agent->debugClient().addMessage( "FreeKick:Turn" );
Body_TurnToPoint( face_point ).execute( agent );
agent->setNeckAction( new Neck_ScanField() );
return true;
}
if ( wm.seeTime() != wm.time()
|| wm.self().stamina() < ServerParam::i().staminaMax() * 0.9 )
{
Body_TurnToBall().execute( agent );
agent->setNeckAction( new Neck_ScanField() );
agent->debugClient().addMessage( "FreeKick:Wait%d", wm.setplayCount() );
dlog.addText( Logger::TEAM,
__FILE__": (doKickWait) no see or recover" );
return true;
}
return false;
}
/*-------------------------------------------------------------------*/
/*!
*/
void
Bhv_SetPlayFreeKick::doMove( PlayerAgent * agent )
{
const WorldModel & wm = agent->world();
dlog.addText( Logger::TEAM,
__FILE__": (doMove)" );
Vector2D target_point = Strategy::i().getPosition( wm.self().unum() );
if ( wm.setplayCount() > 0
&& wm.self().stamina() > ServerParam::i().staminaMax() * 0.9 )
{
const PlayerObject * nearest_opp = agent->world().getOpponentNearestToSelf( 5 );
//存在对方球员在抢球区
if ( nearest_opp && nearest_opp->distFromSelf() < 3.0 )
{
Vector2D add_vec = ( wm.ball().pos() - target_point );
add_vec.setLength( 3.0 );
long time_val = agent->world().time().cycle() % 60;
if ( time_val < 20 )
{
}
else if ( time_val < 40 )
{
target_point += add_vec.rotatedVector( 90.0 );
}
else
{
target_point += add_vec.rotatedVector( -90.0 );
}
target_point.x = min_max( - ServerParam::i().pitchHalfLength(),
target_point.x,
+ ServerParam::i().pitchHalfLength() );
target_point.y = min_max( - ServerParam::i().pitchHalfWidth(),
target_point.y,
+ ServerParam::i().pitchHalfWidth() );
}
}
target_point.x = std::min( target_point.x,
agent->world().offsideLineX() - 0.5 );
//下面的代码是修改冲刺的体力
double dash_power
= Bhv_SetPlay::get_set_play_dash_power( agent );
double dist_thr = wm.ball().distFromSelf() * 0.07;
if ( dist_thr < 1.0 ) dist_thr = 1.0;
agent->debugClient().addMessage( "SetPlayMove" );
agent->debugClient().setTarget( target_point );
agent->debugClient().addCircle( target_point, dist_thr );
if ( ! Body_GoToPoint( target_point,
dist_thr,
dash_power
).execute( agent ) )
{
// already there
Body_TurnToBall().execute( agent );
}
if ( wm.self().pos().dist( target_point )
> std::max( wm.ball().pos().dist( target_point ) * 0.2, dist_thr ) + 6.0
|| wm.self().stamina() < ServerParam::i().staminaMax() * 0.7 )
{
if ( ! wm.self().staminaModel().capacityIsEmpty() )
{
agent->debugClient().addMessage( "Sayw" );
agent->addSayMessage( new WaitRequestMessage() );
}
}
agent->setNeckAction( new Neck_TurnToBallOrScan() );
}
这几天一直在寻找有关策略的相关资料,但是还没有确定如何下手,初步设想是从阵型开始入手,然后就修改球员之间的跑位和信息交流等。在修改之前,还需要时间去进一步巩固一下相关的代码。