📄 decision.cpp
字号:
//对应函数: return DPosition;//目标点为:
Vector dest=(predictedBall.Get_vPos().x-20, predictedBall.Get_vPos().y+10);//100为经验常数
g_MyTeam[MainDeffenser1].MoveToWithAngleOA(dest,180);
}
void CDecision::DAssistantA() //辅助防守球员的选择及动作判断
{
DeffenseAssistant=DAssistant();
Vector TurnPt;
if( g_MyTeam[DeffenseAssistant].HaveObstacle(currentBall.Get_vPos()) )
//机器人与球之间没有障碍
{
//return moveto;
g_MyTeam[DeffenseAssistant].MoveTo(currentBall.Get_vPos());
}
//对应函数:return DPosition;//目标点的选取为:
//已知球坐标(b1,b2),我方球门中点(d1,d2),防守跑位队员的坐标(p1,p2)
/*已处在防守时,目标点的选取为:
//以球门中心为端点,分别向防守跑位队员和球方向做两条射线,求其角平分线与直线x=p1的交点作为防守跑外队员的目标点
a1=arctan(b1-d1,b2-d2);//arctan反三角函数
a2=arctan(p1-d1,p2-d2);
a=(a1+a2)/2;
y=tan(a)*(p1-d1)+d2;//目标点为(p1,y);
g_MyTeam[DeffenseAssistant].MoveToWithAngleOA(currentBall.Get_vPos(),180);
}
*/
/*
void CDecision::DFreeManA()
{
DeffenseFreeMan=DFreeMan();
if( currentBall.Get_vPos().x<=g_MyTeam[DeffenseFreeMan].Get_vPos().x )//当球在freeman的后面时
{
//进行防守跑位return DPosition;
g_MyTeam[DeffenseFreeMan].MoveToWithAngleOA(predictedBall.Get_vPos(),180);
}
else
{
if( tn(DeffenseFreeMan)<=PI/4)//当球在freeman的前面,且freeman的位置以及朝向角和球的位置成一定的关系;则启用射门动作
{
// return shoot;//
}
// return block;//目标点为球
g_MyTeam[DeffenseFreeMan].MoveTo(currentBall.Get_vPos());
}
}
*/
void CDecision::ChooseDots(Player &player)
{
Vector r=g_Ball.Get_vPos()-player.Get_vPos();
// if(JudgeRole(player)==ATTACK)//进攻时的选点半径
// {
if(r.mod()>200)
{
this->Radius=150;
}
else if( (r.mod()>100) && (r.mod()<=200) )
{
this->Radius=100;
}
else if(r.mod()<=100)
{
this->Radius=r.mod();
}
// }
/* else//防守时(在球的前方)的选点半径
{
if(r.mod()>200)
{
this->Radius=150;
}
if( (r.mod()>100) && (r.mod()<=200) )
{
this->Radius=100;
}
if(r.mod()<=100)
{
this->Radius=r.mod();
}
if(r.mod()<JUDGEDIST)
{
this->Radius=2*r.mod();
}
}
*/ double x=0;
double y=0;
for(int i=0; i<NUM; i++)
{
x=player.Get_vPos().x+Radius*cos((player.Get_m_Angle()-i*(360/NUM))*(pi/180));
y=player.Get_vPos().y+Radius*sin((player.Get_m_Angle()-i*(360/NUM))*(pi/180));
Dot[i]=Vector(x,y);
}
}
int CDecision::ComputeIndex1(Player &player )
{//主攻或者主防者的计算进攻性系数,返回动作标号,默认目标就是球
Vector r= g_Ball.Get_vPos() - player.Get_vPos() ;
Vector r1= player.Get_vPos() - g_Ball.Get_vPos() ;
int k=0;
double bound[NUM];
double obstacle[NUM];
double dis[NUM];
double vector[NUM];
if( (fabs(r.GetAngle()-player.Get_m_Angle())<40 )&& (player.HaveObstacle(g_Ball.Get_vPos())==FALSE ) )
{
return 0;
}
if( (fabs(r1.GetAngle()-player.Get_m_Angle())<40)&&(player.HaveObstacle(g_Ball.Get_vPos())==FALSE ))
{
return 6;
}
if( r.mod()>SHOOTDIST )//在球的后方的SHOOTDIST距离处
{
for(int i=0; i<NUM; i++)
{
if( (Dot[i].x>TOP)||(Dot[i].x<BOTTOM)||(Dot[i].y<RIGHT)||(Dot[i].y>LEFT) )
bound[i]=0;
else
bound[i]=1;
}
for( i=0; i<NUM; i++)
{
if(player.HaveObstacle(Dot[i])==TRUE )
{
obstacle[i]=0;
}
else
{
obstacle[i]=1;
}
}
for(i=0; i<NUM; i++)
{
Vector d=Vector(g_Ball.Get_vPos().x-Dot[i].x, g_Ball.Get_vPos().y-Dot[i].y);
dis[i]=1-(d.mod()/(Radius+r.mod()));
}
for(i=0; i<NUM;i++)
{
index[i]=bound[i]*obstacle[i]*dis[i];
}
double t=0;
for(i=0; i<NUM; i++)
{
if(index[i]>t)
{
t=index[i];
k=i;
}
}
}
else //进攻中近处(射门)的处理,如何射门!!!!!!!!!!!!!!!!!!!!
{ //射门!!!!!!!!!!!!!!!!!!!!!!
for(int i=0; i<NUM; i++)
{
if( (Dot[i].x>TOP)||(Dot[i].x<BOTTOM)||(Dot[i].y<RIGHT)||(Dot[i].y>LEFT) )
bound[i]=0;
else
bound[i]=1;
}
for( i=0; i<NUM; i++)
{
if(player.HaveObstacle(Dot[i])==TRUE )
{
obstacle[i]=0;
}
else
{
obstacle[i]=1;
}
}
//以下为第一种射门方案
/* for(i=0; i<NUM; i++)//越近越好---------未必!!应该以角度来计算!!
{
if(Dot[i].x<player.Get_vPos().x)
{
dis[i]=0;
}
else
{
dis[i]=1;
}
}
for( i=0; i<NUM; i++ )
{
Vector a=Vector(g_Ball.Get_vPos().x-Dot[i].x,g_Ball.Get_vPos().y-Dot[i].y);
Vector b=Vector(m_OpponentGoal.x-Dot[i].x, m_OpponentGoal.y-Dot[i].y);
vector[i]=(fabs(a.GetAngle()-b.GetAngle() )/180 );
}
for(i=0; i<NUM;i++)
{
index[i]=bound[i]*obstacle[i]*dis[i]*vector[i];
}
*/
//以下为第二种方案,角度为主要考虑点
double behind[NUM];
for(i=0; i<NUM; i++)
{
if(Dot[i].x<g_Ball.Get_vPos().x)
{
behind[i]=1;
}
else
{
behind[i]=0;
}
}
Vector a=m_OpponentGoal-g_Ball.Get_vPos();
for( i=0; i<NUM; i++ )
{
Vector b=Vector(m_OpponentGoal.x-Dot[i].x, m_OpponentGoal.y-Dot[i].y);
vector[i]=1-(fabs(a.GetAngle()-b.GetAngle() )/180 );
}
for(i=0; i<NUM;i++)
{
index[i]=bound[i]*obstacle[i]*vector[i]*behind[i];
}
double t=0;
for(i=0; i<NUM; i++)
{
if(index[i]>t)
{
t=index[i];
k=i;
}
}
}
return k;
}
int CDecision::ComputeIndex2(Player &player)
{//防守计算权值
Vector r=g_Ball.Get_vPos()-player.Get_vPos();
Vector r1=player.Get_vPos()-g_Ball.Get_vPos();
Vector TurnPt;
double vector[NUM];
double bound[NUM];
double obstacle[NUM];
double dis[NUM];
int k=0;
if(r.mod()<15)
{
return 15;
}
if( r.mod()>JUDGEDIST )//大于正向处理的距离时
{
if( (fabs(r.GetAngle()-player.Get_m_Angle())<40 )&& (player.HaveObstacle(g_Ball.Get_vPos())==FALSE ) )
{
return 0;
}
if( (fabs(r1.GetAngle()-player.Get_m_Angle())<50)&&(player.HaveObstacle(g_Ball.Get_vPos())==FALSE ))
{
return 6;
}
for(int i=0; i<NUM; i++)
{
if( (Dot[i].x>TOP)||(Dot[i].x<BOTTOM)||(Dot[i].y<RIGHT)||(Dot[i].y>LEFT) )
bound[i]=0;
else
bound[i]=1;
}
for( i=0; i<NUM; i++)
{
Vector TurnPt;
if(player.HaveObstacle(Dot[i])==TRUE )
{
obstacle[i]=0;
}
else
{
obstacle[i]=1;
}
}
for(i=0; i<NUM; i++)
{
Vector d=Vector(g_Ball.Get_vPos().x-Dot[i].x, g_Ball.Get_vPos().y-Dot[i].y);
dis[i]=1-( d.mod()/ (Radius+r.mod() ) );
}
for(i=0; i<NUM;i++)
{
index[i]=bound[i]*obstacle[i]*dis[i];
}
double t=0;
for(i=0; i<NUM; i++)
{
if(index[i]>t)
{
t=index[i];
k=i;
}
}
}
else//正向处理动作!!!!运动到球的后面!!!!
{
for (int i=0; i<NUM; i++)
{
if( player.bIsHaveObstacle(g_Ball.Get_vPos(), Dot[i])==TRUE )
{
obstacle[i]=0;
}
else
{
obstacle[i]=1;
}
}
double behind[NUM];
for( i=0; i<NUM; i++ )
{
if(Dot[i].x>g_Ball.Get_vPos().x)
{
behind[i]=0;
}
else
{
behind[i]=1;
}
}
for( i=0; i<NUM; i++ )
{
Vector dandb=Dot[i]-g_Ball.Get_vPos();
dis[i]=2*Radius-dandb.mod();
}
for( i=0; i<NUM; i++ )
{
index[i]=obstacle[i]*dis[i]*behind[i];
}
double t=0;
for(i=0; i<NUM; i++)
{
if(index[i]>t)
{
t=index[i];
k=i;
}
}
//所有的点全都被淘汰下的情况
if( (k==0)&& (fabs(r.GetAngle()-player.Get_m_Angle())<45) )
{
if( (player.Get_vPos().y>g_Ball.Get_vPos().y)&&(fabs(r.GetAngle()-player.Get_m_Angle())<45 ))
{//右后方走
k=4;
}
if( (player.Get_vPos().y<g_Ball.Get_vPos().y)&&(fabs(r.GetAngle()-player.Get_m_Angle())<45 ))
{//左后方走
k=8;
}
//机器人与球之间的连线以及与机器人的朝向不在一条直线上时
if( player.Get_vPos().y>g_Ball.Get_vPos().y)
{
k=11;
}
if( player.Get_vPos().y<g_Ball.Get_vPos().y)
{
k=1;
}
}
}
return k;
}
int CDecision::JudgeRole(Player &player)
{
if( player.Get_vPos().x>=g_Ball.Get_vPos().x)
{
return DEFFENSE;
}
return ATTACK;
}
/*
void CDecision::ChooseFTwo1(Ball ball)
{//将在球后面的四个中最靠近球的两个的标号存放到Num[0]和Num[1]中
double t=10000;
int k=0;
for(int i=0; i<4; i++)
{
if(g_MyTeam[i].Get_vPos().x<ball.Get_vPos().x)
{
Vector d=Vector(ball.Get_vPos().x-g_MyTeam[i].Get_vPos().x,ball.Get_vPos().y-g_MyTeam[i].Get_vPos().y);
if(d.mod()<t)
{
t=d.mod();
k=i;
}
}
}
Num[0]=k;
k=0;
t=0;
for(i=0; i<4; i++)
{
if( (i!=Num[0])&& (g_MyTeam[i].Get_vPos().x<ball.Get_vPos().x))
{
Vector d=Vector(ball.Get_vPos().x-g_MyTeam[i].Get_vPos().x,ball.Get_vPos().y-g_MyTeam[i].Get_vPos().y);
if(d.mod()<t)
{
t=d.mod();
k=i;
}
}
}
Num[1]=k;
}
*/
/*
int CDecision::RobotsBehindBall(Ball ball)
{
int k=0;
for(int i=0; i<4; i++)
{
if(g_MyTeam[i].Get_vPos().x<g_Ball.Get_vPos().x)
{
k++;
}
}
return k;
}
*/
/*
void CDecision::ChooseLTwo()
{//将剩下的两个的标号纪录在Num[2]和Num[3]中
for(int i=0; i<4; i++)
{
if( (i!=Num[0]) && (i!=Num[1]) )
{
Num[2]=i;
}
}
for( i=0; i<4; i++)
{
if( (i!=Num[0]) && (i!=Num[1]) && (i!=Num[2]))
{
Num[3]=i;
}
}
}
*/
/*
void CDecision::ChooseFTwo2(Ball ball)
{//最靠近球的两个的标号存放到Num[0]和Num[1]中
double t=10000;
int k=0;
for(int i=0; i<4; i++)
{
Vector d=Vector(ball.Get_vPos().x-g_MyTeam[i].Get_vPos().x,ball.Get_vPos().y-g_MyTeam[i].Get_vPos().y);
if(d.mod()<t)
{
t=d.mod();
k=i;
}
}
Num[0]=k;
k=0;
t=0;
for(i=0; i<4; i++)
{
if( i!=Num[0] )
{
Vector d=Vector(ball.Get_vPos().x-g_MyTeam[i].Get_vPos().x,ball.Get_vPos().y-g_MyTeam[i].Get_vPos().y);
if(d.mod()<t)
{
t=d.mod();
k=i;
}
}
}
Num[1]=k;
}
*/
void CDecision::ChooseMain(Ball ball)
//球为目标点,如果球后面除了守门员还有其他机器人则选择最靠前的,如果没有则选择球前面最靠后的
{//先不用
double t=10000;
int k=6;
for(int i=0; i<4; i++)
{
Vector d=Vector(ball.Get_vPos().x-g_MyTeam[i].Get_vPos().x,ball.Get_vPos().y-g_MyTeam[i].Get_vPos().y);
if(g_MyTeam[i].Get_vPos().x<ball.Get_vPos().x)
{
if(d.mod()<t)
{
t=d.mod();
k=i;
}
}
}
if(k==6)//说明没有选出机器人来
{
t=10000;
for(i=0; i<4; i++)
{
Vector d=ball.Get_vPos()-g_MyTeam[i].Get_vPos();
if(d.mod()<t)
{
t=d.mod();
k=i;
}
}
}
Num[0]=k;//将主攻者的标号放在Num[0]中
}
void CDecision::ChooseSecond(Ball ball)//副攻为离球最近的机器人
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -