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

📄 analyzer.cpp

📁 The application wizard has created this SoccerDoctor application for you. This application not onl
💻 CPP
📖 第 1 页 / 共 5 页
字号:
							tempEvent.type=BB_PASS;
						tempEvent.pt.x=vPlayerPosition[vPlayerPosition.size()-2].ball.x;
						tempEvent.pt.y=vPlayerPosition[vPlayerPosition.size()-2].ball.y;
						tempEvent.obj.pt.x=_sCycleInfo.ball.x;
						tempEvent.obj.pt.y=_sCycleInfo.ball.y;
						tempEvent.obj.unum=player;
						vBasicEvent.push_back(tempEvent);
						//回填参数
						if(vBasicEvent[vBasicEvent.size()-2].success && vBasicEvent[vBasicEvent.size()-2].type!=BB_SHOOT){
							vBasicEvent[vBasicEvent.size()-2].obj.pt.x=vPlayerPosition[vPlayerPosition.size()-2].ball.x;
							vBasicEvent[vBasicEvent.size()-2].obj.pt.y=vPlayerPosition[vPlayerPosition.size()-2].ball.y;
							vBasicEvent[vBasicEvent.size()-2].endTime=_sCycleInfo.time;
						}
					}else{
						//判断为清球
					}
				}
				//处理改周期断球的基本行为事件队列
				tempEvent.time=_sCycleInfo.time;
				tempEvent.endTime=_sCycleInfo.time;
				tempEvent.team=_sInnerState.teamWithBall;
				tempEvent.player=_sInnerState.playerWithBall;
				tempEvent.type=BB_INTERCEPT;
				tempEvent.success=true;
				tempEvent.pt.x=_sCycleInfo.ball.x;
				tempEvent.pt.y=_sCycleInfo.ball.y;
				vBasicEvent.push_back(tempEvent);
				//回填参数
				if(vBasicEvent[vBasicEvent.size()-2].type!=BB_INTERCEPT)
					if(!(vBasicEvent[vBasicEvent.size()-2].type==BB_SHOOT && vBasicEvent[vBasicEvent.size()-2].success)){
						vBasicEvent[vBasicEvent.size()-2].success=false;
						if(vBasicEvent[vBasicEvent.size()-2].success){
							vBasicEvent[vBasicEvent.size()-2].obj.pt.x=_sCycleInfo.ball.x;
							vBasicEvent[vBasicEvent.size()-2].obj.pt.y=_sCycleInfo.ball.y;
							vBasicEvent[vBasicEvent.size()-2].endTime=_sCycleInfo.time;
						}
					}
			}else if(_sInnerState.prePlayerWithBall!=_sInnerState.playerWithBall){
				//传球或接球
				tempEvent.time=_sCycleInfo.time-1;
				tempEvent.endTime=_sCycleInfo.time;
				tempEvent.team=_sInnerState.lastCycleTeamWithBall;
				tempEvent.player=_sInnerState.lastCyclePlayerWithBall;
				tempEvent.type=BB_PASS;
				tempEvent.pt.x=vPlayerPosition[vPlayerPosition.size()-2].ball.x;
				tempEvent.pt.y=vPlayerPosition[vPlayerPosition.size()-2].ball.y;
				tempEvent.obj.unum=_sInnerState.playerWithBall;
				tempEvent.success=true;
				vBasicEvent.push_back(tempEvent);
				//回填参数
				if(vBasicEvent[vBasicEvent.size()-2].success){
					vBasicEvent[vBasicEvent.size()-2].obj.pt.x=_sCycleInfo.ball.x;
					vBasicEvent[vBasicEvent.size()-2].obj.pt.y=_sCycleInfo.ball.y;
					vBasicEvent[vBasicEvent.size()-2].endTime=_sCycleInfo.time;
				}
				tempEvent.time=_sCycleInfo.time;
				tempEvent.endTime=_sCycleInfo.time;
				tempEvent.player=_sInnerState.playerWithBall;
				tempEvent.type=BB_RECEIVE;
				tempEvent.obj.unum=_sInnerState.prePlayerWithBall;
				tempEvent.success=true;
				vBasicEvent.push_back(tempEvent);
				//回填参数
				if(vBasicEvent[vBasicEvent.size()-2].success){
					vBasicEvent[vBasicEvent.size()-2].obj.pt.x=_sCycleInfo.ball.x;
					vBasicEvent[vBasicEvent.size()-2].obj.pt.y=_sCycleInfo.ball.y;
					vBasicEvent[vBasicEvent.size()-2].endTime=_sCycleInfo.time;
				}
			}else{
				//调整球
				if(vBasicEvent[vBasicEvent.size()-1].player==_sInnerState.playerWithBall
					&& _sCycleInfo.pmode!=PM_FreeKick_Left && _sCycleInfo.pmode!=PM_FreeKick_Right){
					if(vBasicEvent[vBasicEvent.size()-1].type==BB_ADJUST)
						vBasicEvent[vBasicEvent.size()-1].type=BB_DRIBBLE;
					else if(vBasicEvent[vBasicEvent.size()-1].type!=BB_DRIBBLE){
						tempEvent.time=_sCycleInfo.time;
						tempEvent.endTime=_sCycleInfo.time;
						tempEvent.team=_sInnerState.teamWithBall;
						tempEvent.player=_sInnerState.playerWithBall;
						tempEvent.type=BB_ADJUST;
						tempEvent.pt.x=vPlayerPosition[vPlayerPosition.size()-2].ball.x;//_sCycleInfo.ball.x;
						tempEvent.pt.y=vPlayerPosition[vPlayerPosition.size()-2].ball.y;//_sCycleInfo.ball.y;
						tempEvent.success=true;
						vBasicEvent.push_back(tempEvent);
						//回填参数
						if(vBasicEvent[vBasicEvent.size()-2].success){
							vBasicEvent[vBasicEvent.size()-2].obj.pt.x=_sCycleInfo.ball.x;
							vBasicEvent[vBasicEvent.size()-2].obj.pt.y=_sCycleInfo.ball.y;
							vBasicEvent[vBasicEvent.size()-2].endTime=_sCycleInfo.time;
						}
					}else;
				}else if(_sCycleInfo.pmode!=PM_FreeKick_Left && _sCycleInfo.pmode!=PM_FreeKick_Right){
					tempEvent.time=_sCycleInfo.time;
					tempEvent.endTime=_sCycleInfo.time;
					tempEvent.team=_sInnerState.teamWithBall;
					tempEvent.player=_sInnerState.playerWithBall;
					tempEvent.type=BB_ADJUST;
					tempEvent.pt.x=_sCycleInfo.ball.x;
					tempEvent.pt.y=_sCycleInfo.ball.y;
					tempEvent.success=true;
					vBasicEvent.push_back(tempEvent);
					//回填参数
					if(vBasicEvent[vBasicEvent.size()-2].success){
						vBasicEvent[vBasicEvent.size()-2].obj.pt.x=_sCycleInfo.ball.x;
						vBasicEvent[vBasicEvent.size()-2].obj.pt.y=_sCycleInfo.ball.y;
						vBasicEvent[vBasicEvent.size()-2].endTime=_sCycleInfo.time;
					}
				}else;
			}
		}
	}else if(_sInnerState.lastCycleBallKickableForPlayer){
		//上一个周期有球员踢到球这个周期没有
		//说明有球员释放了球但是有几种可能
		//上一个周期的动作有可能是射门、传球、快速带球、解围或者是失误
		int shootSide;
		if(_sInnerState.lastCyclePlayerWithBall<11)
			shootSide=1;
		else
			shootSide=0;
		double shootProbability=caclShootProbability(shootSide);
		BasicBehaviorEvent tempEvent;
		if(shootProbability>SHOOTPROBABILITYTHRESHOLD){
			//判断为射门然后按上一个周期的参数添加入基本行为事件队列
			tempEvent.time=_sCycleInfo.time-1;
			tempEvent.endTime=_sCycleInfo.time;
			tempEvent.team=_sInnerState.lastCycleTeamWithBall;
			tempEvent.player=_sInnerState.lastCyclePlayerWithBall;
			tempEvent.type=BB_SHOOT;
			tempEvent.pt.x=vPlayerPosition[vPlayerPosition.size()-2].ball.x;
			tempEvent.pt.y=vPlayerPosition[vPlayerPosition.size()-2].ball.y;
			double tmpX=shootSide?FIELDLENGTH/2:-FIELDLENGTH/2;
			tempEvent.obj.pt.x=tmpX;
			tempEvent.obj.pt.y=(_sCycleInfo.ball.y+_sCycleInfo.ball.deltay/_sCycleInfo.ball.deltax*(tmpX-_sCycleInfo.ball.x));
			tempEvent.success=true;
			vBasicEvent.push_back(tempEvent);
			//回填参数
			if(vBasicEvent[vBasicEvent.size()-2].success){
				vBasicEvent[vBasicEvent.size()-2].obj.pt.x=vPlayerPosition[vPlayerPosition.size()-2].ball.x;
				vBasicEvent[vBasicEvent.size()-2].obj.pt.y=vPlayerPosition[vPlayerPosition.size()-2].ball.y;
				vBasicEvent[vBasicEvent.size()-2].endTime=_sCycleInfo.time;
			}
		}else{
			int player=getFastestPlayerToBall(true,_sInnerState.lastCyclePlayerWithBall);
			if(player!=-1 && areTeammate(player,_sInnerState.lastCyclePlayerWithBall)){
				//判断为传球或者带球
				tempEvent.time=_sCycleInfo.time-1;
				tempEvent.endTime=_sCycleInfo.time;
				tempEvent.team=_sInnerState.lastCycleTeamWithBall;
				tempEvent.player=_sInnerState.lastCyclePlayerWithBall;
				if(player==_sInnerState.lastCyclePlayerWithBall)
					//带球
					tempEvent.type=BB_DRIBBLE;
				else
					//传球
					tempEvent.type=BB_PASS;
				tempEvent.pt.x=vPlayerPosition[vPlayerPosition.size()-2].ball.x;
				tempEvent.pt.y=vPlayerPosition[vPlayerPosition.size()-2].ball.y;
				tempEvent.obj.unum=player;
				vBasicEvent.push_back(tempEvent);
				//回填参数
				if(vBasicEvent[vBasicEvent.size()-2].success){
					vBasicEvent[vBasicEvent.size()-2].obj.pt.x=vPlayerPosition[vPlayerPosition.size()-2].ball.x;
					vBasicEvent[vBasicEvent.size()-2].obj.pt.y=vPlayerPosition[vPlayerPosition.size()-2].ball.y;
					vBasicEvent[vBasicEvent.size()-2].endTime=_sCycleInfo.time;
				}
			}else{
				//判断为清球
				tempEvent.time=_sCycleInfo.time-1;
				tempEvent.endTime=_sCycleInfo.time;
				tempEvent.team=_sInnerState.lastCycleTeamWithBall;
				tempEvent.player=_sInnerState.lastCyclePlayerWithBall;
				tempEvent.type=BB_CLEARBALL;
				tempEvent.pt.x=vPlayerPosition[vPlayerPosition.size()-2].ball.x;
				tempEvent.pt.y=vPlayerPosition[vPlayerPosition.size()-2].ball.y;
				vBasicEvent.push_back(tempEvent);
				//回填参数
				if(vBasicEvent[vBasicEvent.size()-2].success){
					vBasicEvent[vBasicEvent.size()-2].obj.pt.x=vPlayerPosition[vPlayerPosition.size()-2].ball.x;
					vBasicEvent[vBasicEvent.size()-2].obj.pt.y=vPlayerPosition[vPlayerPosition.size()-2].ball.y;
					vBasicEvent[vBasicEvent.size()-2].endTime=_sCycleInfo.time;
				}
			}
		}
	}else{
		//这个周期没有球员踢到球上一个周期也没有
		//没有人踢到球的情况没有变化
		//这两个周期的行为可能是拦截球或者跑位
	}
	
	//更新内部状态
	//如果有能踢到球的球员则更新上一次能踢到球
	if(_sInnerState.ballKickableForPlayer){
		_sInnerState.prePlayerWithBall=_sInnerState.playerWithBall;
		_sInnerState.preTeamWithBall=_sInnerState.teamWithBall;
	}


	//射门成功记录更新
	if(_sInnerState.scoreLeft>_sInnerState.lastCycleScoreLeft){
		int i=(int)vBasicEvent.size()-1;
		while(i>0){
			if(vBasicEvent[i].type==BB_SHOOT && vBasicEvent[i].team==0){
					vBasicEvent[i].success=true;
 					break;
			}
			i--;
		}
	}
	if(_sInnerState.scoreRight>_sInnerState.lastCycleScoreRight){
		int i=(int)vBasicEvent.size()-1;
		while(i>0){
			if(vBasicEvent[i].type==BB_SHOOT && vBasicEvent[i].team==1){
					vBasicEvent[i].success=true;
					break;
			}
			i--;
		}
	}


	//复位统计一次调用标志(有待改进)
	if(_sInnerState.statDataInvoked) _sInnerState.statDataInvoked=false;
	if(!_sInnerState.logLoaded)	_sInnerState.logLoaded=true;

	//debug
	//if(_sCycleInfo.time==6000) outputEvents();

	//返回函数正常退出标志
	return 0;
}

int CAnalyzer::getPlayerWithBall()
{
	double dist=-1;
	double minDist=1024;
	double kickableDist=-1;
	int player=-1;
	
	//将上一个周期的记录备份到lastCycle的变量中
	_sInnerState.lastCyclePlayerWithBall=_sInnerState.playerWithBall;
	_sInnerState.lastCyclePlayMode=_sInnerState.playMode;
	_sInnerState.lastCycleBallKickableForPlayer=_sInnerState.ballKickableForPlayer;
	_sInnerState.lastCycleTeamWithBall=_sInnerState.teamWithBall;
	_sInnerState.lastCycleScoreLeft=_sInnerState.scoreLeft;
	_sInnerState.lastCycleScoreRight=_sInnerState.scoreRight;
	//更新这个周期的比分
	_sInnerState.scoreLeft=_sCycleInfo.team[0].score;
	_sInnerState.scoreRight=_sCycleInfo.team[1].score;
	//更新该周期的playmode
	_sInnerState.playMode=_sCycleInfo.pmode;

	//看哪个球员能够踢到球
	for(int i=0;i<(MAX_PLAYER*2);i++){
		//球员离球的距离
		dist=sqrt((_sCycleInfo.ball.x-_sCycleInfo.pos[i].x)*(_sCycleInfo.ball.x-_sCycleInfo.pos[i].x)
					+(_sCycleInfo.ball.y-_sCycleInfo.pos[i].y)*(_sCycleInfo.ball.y-_sCycleInfo.pos[i].y));
		//球员类型号
		int type=_sCycleInfo.pos[i].type;
		//球员参数指针
		const player_type_t* pType=_pMainFrame->getPlayerType(type);
		if(pType!=NULL){
			//球员的踢球范围
			kickableDist=BALL_SIZE+(double)(long)ntohl(pType->kickable_margin)/SHOWINFO_SCALE2+(double)(long)ntohl(pType->player_size)/SHOWINFO_SCALE2;
		}else{
			//球员类型不对
			return -1;
		}
		//如果球员能踢到球且距离球比较近
		if(dist<kickableDist && dist<minDist){
			//记录该球员为当前控球队员
			player=i;
			//记录他距离球的距离
			minDist=dist;
		}
	}
	//假如有队员能踢到球
	if(player!=-1){
		//记录该球员号
		_sInnerState.playerWithBall=player;
		//将该时刻有球员能踢到球的标志置为true
		_sInnerState.ballKickableForPlayer=true;
	}else{
		//假如没有球员能踢到球,这认为最快能拿到球的球员为当前控球队员
		_sInnerState.playerWithBall=getFastestPlayerToBall();
		//将该时刻有球员能踢到球的标志置为false
		_sInnerState.ballKickableForPlayer=false;
	}

	//返回纪录的控球队员号码
	return _sInnerState.playerWithBall;
}

int CAnalyzer::getTeamWithBall()
{
	//先找到可以踢到球的球员
	getPlayerWithBall();

	//如果没有球员能踢到球控球球队置为-1
	if(!_sInnerState.ballKickableForPlayer)
		_sInnerState.teamWithBall=-1;
	else if(_sInnerState.playerWithBall<MAX_PLAYER && _sInnerState.playerWithBall>=0)
		_sInnerState.teamWithBall=0;
	else if(_sInnerState.playerWithBall<MAX_PLAYER*2 && _sInnerState.playerWithBall>=MAX_PLAYER)
		_sInnerState.teamWithBall=1;
	else
		_sInnerState.teamWithBall=-1;
	
	//如果控球球员发生变化则将标志置为true否则为false
	if(_sInnerState.playerWithBall!=_sInnerState.lastCyclePlayerWithBall)
		_sInnerState.playerWithBallChange=true;
	else
		_sInnerState.playerWithBallChange=false;
	
	//如果控球球队发生变化则将相应标志置为true否则置为false
	if(_sInnerState.teamWithBall!=_sInnerState.lastCycleTeamWithBall)
		_sInnerState.teamWithBallChange=true;
	else
		_sInnerState.teamWithBallChange=false;

	//返回控球球队
	return _sInnerState.teamWithBall;
}


//计算最快能拦截到球的球员
int CAnalyzer::getFastestPlayerToBall(bool teammate, int unum)
{
	//复制球速、球的位置
	double ballx=_sCycleInfo.ball.x;
	double bally=_sCycleInfo.ball.y;
	double ballvx=_sCycleInfo.ball.deltax;
	double ballvy=_sCycleInfo.ball.deltay;
	//初始化周期数、标志
	int cycle=0;
	double kickableDist;
	bool found=false;
	double dist;
	int player=-1;

	do{
		//更新周期数
		cycle++;
		//更新球的位置
		ballx+=ballvx;
		bally+=ballvy;
		//更新球的速度
		ballvx*=BALL_DECAY;
		ballvy*=BALL_DECAY;
		//看所有球员看谁在该周期数内能拦截到球
		for(int i=0;i<(MAX_PLAYER*2);i++){
			if(teammate && areTeammate(unum,i) || !teammate){
				dist=sqrt((ballx-_sCycleInfo.pos[i].x)*(ballx-_sCycleInfo.pos[i].x)
							+(bally-_sCycleInfo.pos[i].y)*(bally-_sCycleInfo.pos[i].y))-caclPlayerDashDist(cycle);
				UINT type=_sCycleInfo.pos[i].type;
				const player_type_t* pType=_pMainFrame->getPlayerType(type);
				if(pType!=NULL){
					kickableDist=(double)(long)ntohl(pType->kickable_margin)/SHOWINFO_SCALE2
						+(double)(long)ntohl(pType->player_size)/SHOWINFO_SCALE2;
				}else{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -