⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decision.cpp

📁 本程序是2005年参加中国机器人大赛的比赛程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	//对应函数:	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 + -