由于之前linux版的sublime不支持输入中文,所以我去年在写策略函数时,没有写中文注释。当时写了一些英文注释,但受限于个人英文水平,也是很简单的几处注释。
这里为了大家更好的理解代码,我为策略函数的NaoBehavior::PlayOnSkill()部分补充了中文注释。大家也可以将这段有注释的代码,复制粘贴到strategy.cc中替换掉原来没有注释的代码。
SkillType NaoBehavior::PlayOnSkill()
{
//playerCTB()返回最近球员编号,右键GotoDefinition查看函数
if ( playerCTB() == worldModel->getUNum() ) { //当球员编号等于最近球员编号时
//勾股定理计算球距离球门距离的平方,这里没有开根号是距离的平方
int ballToG = (ball.getX()-15)*(ball.getX()-15)+(ball.getY()-0)*(ball.getY()-0);
//ballToG是距离的平方,小于15约等于距离小于4
if( ballToG >= 15 && ball.getX()>-12 ) //当球门距离大于4且在x=-12右方
{
return kickBall( KICK_DRIBBLE,VecPosition(13,1,0) ); //KICK_DRIBBLE小幅度踢球,适合带球
}else{
return kickBall( KICK_IK,VecPosition(15,0,0) ); //KICK_IK中距离踢球,适合射门,抢救
}
}else{
VecPosition temp2;
temp2 = worldModel-> getMyPosition();
//1~3号为守门员
if(worldModel->getUNum()==1){
return SKILL_STAND;
/* 这里只有1号守门员在固定位置不动,2、3的x坐标不变,在y方向上下移动,保证1、2、3与球连成4点一线 */
/* 这里利用球的坐标与球门坐标的相位(x,y)计算了一个斜率k,带入2、3的固定x坐标,计算出2、3的y坐标 */
}else if(worldModel->getUNum()==2 ){
if(ball.getX()>-13){
double k=(-ball.getY())/(-HALF_FIELD_X +1-ball.getX());
double y=(-HALF_FIELD_X +2-ball.getX())*k+ball.getY();
return goToTarget(VecPosition(-HALF_FIELD_X +2, y , 0 ));
}
else{
return SKILL_STAND;
}
}else if(worldModel->getUNum()==3 ){
if(ball.getX()>-12){
double k=( -ball.getY() ) / ( -HALF_FIELD_X + 1 - ball.getX() );
double y=( -HALF_FIELD_X + 3 - ball.getX()) * k + ball.getY();
return goToTarget(VecPosition(-HALF_FIELD_X + 3, y , 0 ));
}
else{
return SKILL_STAND;
}
/* 这里有一个没来及改的BUG,当球的x坐标小于3号的x坐标时,k值可能会过大,使3球员的y坐标超出球场范围发生异常 */
//4~8号在我方半场散布防守
}else if( worldModel->getUNum() <= 8 ){
if( temp2.getDistanceTo(ball) > 5 )
{
int tMove;
if( ball.getY() > 5 ) tMove = 2.5;
else if( ball.getY() <= -5 ) tMove = -2.5;
else tMove =0;
switch( worldModel->getUNum() )
{//这里有个不成熟的功能,让我方半场布防的球员随球位置小幅度平移
case 4:
return goToTarget( VecPosition(-9,3+tMove,0) );
case 5:
return goToTarget( VecPosition(-9,0+tMove,0) );
case 6:
return goToTarget( VecPosition(-9,-3+tMove,0) );
case 7:
return goToTarget( VecPosition(-5,1.5+tMove,0) );
case 8:
return goToTarget( VecPosition(-5,-1.5+tMove,0) );
}
}else{
if ( me.getDistanceTo(ball) < 1 )
{
// Close enough to desired position and orientation so just stand
//当护卫球员距离球过近时停下,避免与最近球员碰撞
return SKILL_STAND;
}
else
{
// Move toward target location 向目标位置移动
return goToTarget( VecPosition( ball.getX()-2 , ball.getY() , 0 ) );
}
}
//9、10、11为前锋
}else if(worldModel->getUNum() >= 9){
int leftUNum,rightUNum; //定义了左球员和右球员
switch( playerCTB() ) //判断最近球员,让另外两名在最近球员左右前方援护
{
case 9:
leftUNum = 10; rightUNum = 11;
break;
case 10:
leftUNum = 9; rightUNum = 11;
break;
case 11:
leftUNum = 9; rightUNum = 10;
break;
default:
leftUNum = 9; rightUNum = 11;
}
if (me.getDistanceTo(ball) < 1)
{
// Close enough to desired position and orientation so just stand
// 当护卫球员距离球过近时停下,避免与最近球员碰撞
return SKILL_STAND;
}
else
{
if( worldModel->getUNum() == leftUNum ) //左护卫在左前方援护
return goToTarget( VecPosition( ball.getX()+1.2 , ball.getY()+1.3 , 0 ) );
else if(worldModel->getUNum() == rightUNum ) //右护卫在右前方援护
return goToTarget( VecPosition( ball.getX()+1.2 , ball.getY()-1.3 , 0 ) );
else //不是任何护卫时,跟在后方援护
return goToTarget( VecPosition( ball.getX()-1 , ball.getY() , 0 ) );
}
}
}
return SKILL_STAND; //保险措施:如果球员不满足以上任何条件,停止不动
}
另外我修改了一处bug,就是这段代码的第8行的条件。将||
改成了&&
,修复了球队射门功能异常。这个问题在之前比赛时没有明显显露,但是在单独测试时发现了。仔细检查后注意到这里的条件关系写错了。