📄 analyzer.cpp
字号:
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 + -