📄 decision.cpp
字号:
{//先不用
int k=0;
double t=10000;
for(int 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;//将第二个机器人的标号放在Num[1]中
}
void CDecision::ChooseThird(Ball ball)//防守为最靠后的机器人
{//先不用
int k=0;
double t=10000;
for(int i=0; i<4; i++)
{
if( (i!=Num[0])&& (i!=Num[1]) && (g_MyTeam[i].Get_vPos().x<t) )
{
t=g_MyTeam[i].Get_vPos().x;
k=i;
}
}
Num[2]=k;
}
void CDecision::ChooseFouth()//剩下的即为自由人或者防守队员
{//先不用
int k=0;
for(int i=0;i<4; i++)
{
if( (i!=Num[0])&&(i!=Num[1])&&(i!=Num[2])) k=i;
}
Num[3]=k;
}
//主攻者(主防者)运动点永远对着球
void CDecision::IntegratedAction(Player &player)
{
int n;
ChooseDots(player);
// if(JudgeRole(player)==ATTACK)//如果为进攻型则用进攻权值计算
// {
n=ComputeIndex1(player);
// }
// else//防守时的点的权值计算
// {
// n=ComputeIndex2(player);
// }
player.SimpleAction(n);
}
void CDecision::ChooseNorDots(Player &player, Vector des)
{//一般运动的选点情况,根据目标点来选择,此时不需要考虑正向处理等等
Vector r=des-player.Get_vPos();
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();
}
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::ComputeNorIndex(Player &player, Vector des)
{ //一般性的跑位的选点并且返回对应的动作编号
Vector r=Vector(des.x-player.Get_vPos().x,des.y-player.Get_vPos().y);
Vector r1=Vector(player.Get_vPos().x-des.x,player.Get_vPos().y-des.y);
int k=0;
double bound[NUM];
double obstacle[NUM];
double dis[NUM];
if( (des.x>player.Get_vPos().x) && (r.mod()<40 ) )
{
return 15;
}
if( (fabs(r.GetAngle()-player.Get_m_Angle())<50 )&& (player.HaveObstacleBall(des)==FALSE ) )
{
return 0;
}
if( (fabs(r1.GetAngle()-player.Get_m_Angle())<50)&&(player.HaveObstacleBall(des)==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++)
{
if(player.HaveObstacleBall(Dot[i])==TRUE )
{
obstacle[i]=0;
}
else
{
obstacle[i]=1;
}
}
for(i=0; i<NUM; i++)
{
Vector d=Vector(des.x-Dot[i].x, des.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;
}
}
return k;
}
void CDecision::NorIntegratedAction(Player &player, Vector des)
{
int n;
ChooseNorDots(player,des);
n=ComputeNorIndex(player,des);
player.SimpleAction(n);
}
//下为下半场的函数程序
int CDecision::JudgeRoleSecondHalf(Player &player)
{
if( player.Get_vPos().x<g_Ball.Get_vPos().x)
{
return DEFFENSE;
}
return ATTACK;
}
void CDecision::IntegratedActionSecondHalf(Player &player)//对球运动的动作的集成
{
int n;
ChooseDotsSecondHalf(player);
if(JudgeRoleSecondHalf(player)==ATTACK)//如果为进攻型则用进攻权值计算
{
n=ComputeIndex1(player);
}
else//防守时的点的权值计算
{
n=ComputeIndex2(player);
}
player.SimpleAction(n);
}
void CDecision::ChooseDotsSecondHalf(Player &player)
{
Vector r=g_Ball.Get_vPos()-player.Get_vPos();
if(JudgeRoleSecondHalf(player)==ATTACK)//进攻时的选点半径
{
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();
}
}
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);
}
}
/*
void CDecision::AllLeaveTheBall()
{
Vector pt[10],d;
int p[10],n,i;
double t=10000.1,x,y;
int k=0;
Vector d2;
for(i=0; i<5; i++)
{
d=g_MyTeam[i].Get_vPos()-g_Ball.Get_vPos();
for(n=0; n<10; n++ )
{
x=g_Ball.Get_vPos().x+100*cos( d.GetAngle()-n*(pi/180) );//100为选择半径
y=g_Ball.Get_vPos().y+100*sin( d.GetAngle()-n*(pi/180) );
if( (x>TOP)||(x<BOTTOM)||(y<RIGHT)||(y>LEFT) )
p[n]=0;
else
{
p[n]=1;
pt[n]=Vector(x,y);
}
}
if( d.mod()<STDDISTANT )//如果本方中的一些机器人没有达到要求则运动到最近的供选择的点
{
for( n=0; n<10; n++)
{
d2=pt[n]-g_MyTeam[i].Get_vPos();
if( (p[n]==1) && ( d2.mod()<t ) )//选出距离最近的有效点然后运动到该点
{
t=d2.mod();
k=n;
}
}
NorIntegratedAction(g_MyTeam[i],pt[k]);
return ;
}
else
{
g_MyTeam[i].BasicAct(0,0,0,0);
return ;
}
}
}
*/
void CDecision::GoalieMove(Player &player)
{ //机器人应该正向向左放置
//一般来说,目标点都在门前的直线上,但是是否需要转圈是由球的位置而定
//如果偏角不是很大则直接横着走
Vector dis=g_Ball.Get_vPos()-player.Get_vPos();
Vector dest=player.Get_vPos()-g_Ball.Get_vPos();
if(g_Ball.Get_vPos().x>GOALIEDIST)
{
player.BasicAct(0,0,0,0);
return;
}
else
{
Vector m_GoaliePoint=player.ChooseGoalieP(g_Ball);
NorIntegratedAction(player,m_GoaliePoint);
return;
}
}
void CDecision::LShooter(Player &player)
{
if( g_Ball.m_vPos.x<MIDDLEPOINTX )
{
player.BasicAct(0,0,0,0);
return;
}
else
{
if( g_Ball.m_vPos.y < MIDDLEPOINTY )
{
player.BasicAct( 0, 0, 0, 0 );
return;
}
else
{
IntegratedAction(player);
return;
}
}
}
void CDecision::RShooter(Player &player)
{
if( g_Ball.Get_vPos().x > MIDDLEPOINTX )
{
player.BasicAct(0,0,0,0);
return;
}
else
{
if( g_Ball.m_vPos.y > MIDDLEPOINTY )
{
player.BasicAct( 0, 0, 0, 0 );
return;
}
else
{
IntegratedAction(player);
return;
}
}
}
void CDecision::LShooterSecondHalf(Player &player)//左前锋
{
if( g_Ball.Get_vPos().x>MIDDLEPOINTX )
{
player.BasicAct(0,0,0,0);
}
else
{
if( (g_Ball.Get_vPos().x>OPPONENTGOALIEX) && (g_Ball.Get_vPos().y<FORBIDDENLY) &&(g_Ball.Get_vPos().y>FORBIDDENRY) )
{
Vector d(g_Ball.Get_vPos().x-40,g_Ball.Get_vPos().y);
NorIntegratedAction(player,d);
}
else
{
IntegratedActionSecondHalf(player);
}
}
}
void CDecision::RShooterSecondHalf(Player &player)//右前锋
{
if( (g_Ball.Get_vPos().x>OPPONENTGOALIEX) && (g_Ball.Get_vPos().y<FORBIDDENLY) &&(g_Ball.Get_vPos().y>FORBIDDENRY) )
{
Vector d(g_Ball.Get_vPos().x-40,g_Ball.Get_vPos().y+20);
NorIntegratedAction(player,d);
}
else
{
IntegratedActionSecondHalf(player);
}
}
void CDecision::FDefense(Player &player)
{
if(g_Ball.Get_vPos().x>MIDDLEPOINTX)//球在所定义的后防线以上时,让机器人随时对者球与球门的连线
{
// Vector FDdest=player.ChooseDP1(g_Ball);
// NorIntegratedAction(player,FDdest);
player.BasicAct( 0, 0, 0, 0 );
return;
}
else
{
IntegratedAction(player);
return;
}
}
void CDecision::SDefense(Player &player)
{
Vector distant=g_Ball.Get_vPos()-m_MyGoal;
if(g_Ball.Get_vPos().x>SDEFFENSEX)//球在后防线以上时,让机器人随时对者球与球门的连线
{
Vector SDdest=player.ChooseDP2(g_Ball);
NorIntegratedAction(player,SDdest);
return;
}
else
{
IntegratedAction(player);
return;
}
}
void CDecision::FDefenseSecondHalf(Player &player)
{
if(g_Ball.Get_vPos().x<AX)//球在所定义的后防线以上时,让机器人随时对者球与球门的连线
{
Vector FDdest=player.ChooseDP2SecondHalf(g_Ball);
NorIntegratedAction(player,FDdest);
}
else
{
IntegratedActionSecondHalf(player);
}
}
void CDecision::SDefenseSecondHalf(Player &player)
{
Vector distant=g_Ball.Get_vPos()-m_OpponentGoal;
if(g_Ball.Get_vPos().x<OPPONENTDIFFENSEX)//球在后防线以上时,让机器人随时对者球与球门的连线
{
Vector SDdest=player.ChooseDP1SecondHalf(g_Ball);
NorIntegratedAction(player,SDdest);
}
else
{
if( (g_Ball.Get_vPos().x>OPPONENTGOALIEX) && (g_Ball.Get_vPos().y<FORBIDDENLY) &&(g_Ball.Get_vPos().y>FORBIDDENRY) )
{
Vector d(g_Ball.Get_vPos().x-40,g_Ball.Get_vPos().y-40);
NorIntegratedAction(player,d);
}
else
{
IntegratedActionSecondHalf(player);
}
}
}
void CDecision::GoalieMoveSecondHalf(Player &player)
{
Vector dis=g_Ball.Get_vPos()-player.Get_vPos();
Vector dest=player.Get_vPos()-g_Ball.Get_vPos();
if(g_Ball.Get_vPos().x<AX)
{
player.BasicAct(0,0,0,0);
return;
}
else
{
if( (g_Ball.Get_vPos().x>OPPONENTGOALIEX) && (g_Ball.Get_vPos().y<FORBIDDENLY) &&(g_Ball.Get_vPos().y>FORBIDDENRY) )
{
player.BasicAct(0,0,0,0);
}
else
{
Vector m_GoaliePoint=player.ChooseGoaliePSecondHalf(g_Ball);
NorIntegratedAction(player,m_GoaliePoint);
}
}
}
void CDecision::IntegratedAction2(Player &player)
{
if(player.Get_vPos().x>g_Ball.Get_vPos().x)
{
Vector des=Vector(g_Ball.Get_vPos().x-80,g_Ball.Get_vPos().y);
NorIntegratedAction(player,des);
}
else
{
Vector bandr=player.Get_vPos()-g_Ball.Get_vPos();
Vector randb=g_Ball.Get_vPos()-player.Get_vPos();
if( (fabs(bandr.GetAngle()-player.Get_m_Angle())<45) &&(fabs(player.Get_m_Angle()-randb.GetAngle())<45) )
{
IntegratedAction(player);
return;
}
else
{
player.TurnTo(g_Ball.Get_vPos());
return;
}
}
}
void CDecision::Boundary(Player &player)
{//在门前边界处理要根据本方和对方采用不同的边界值,本方大,减少乌龙球概率,对方小,增加进门概率,
// 比赛需要当时测试设置变化值。
CRect field=Player::FieldStruct.m_Field;
// CRect door=CVideoDlg::my_Door;
// CString str;
// str.Format("%d,%d,%d,%d",field.Width(),field.Height(),player.Get_vPos().x, player.Get_vPos().y );
// AfxMessageBox(str);
int x=player.Get_vPos().x;
int y=player.Get_vPos().y;
double angle=player.Get_m_Angle();
int limit=30;// 实际测试
isboundary=0;
int doory=int(0.5*abs(Player::FieldStruct.m_Field.Width()));
if(abs(field.Height())-y<=limit && x>=limit && x<=abs(field.Width())-limit)
{
if(angle>=20 && angle<=160)
{
player.slxSimpleAction(-100,-100,250);
}
else if(angle>=-160 && angle<=-20)
{
player.slxSimpleAction(100,100,250);
}
else if (angle>=0 && angle<=20)
{
player.slxSimpleAction(-100,-80,250);
}
else if (angle>=160 && angle<=180)
{
player.slxSimpleAction(-80,-100,250);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -