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

📄 interception.cpp

📁 2002年
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	for(i = 0; i<num_total; i++){
		p = &GetPlayer(FieldInfo.Players_Close2Ball[i]);
		SetITPlayer(p);
		if(reset){
			if(!p->bodyfc_guessed){  
				getinterceptioninfo(ballpos, ballvel, p->pos, p->global_vel, p->bodyfacing, p->IT_inf);
			}else{
				getinterceptioninfo(ballpos, ballvel, p->pos, p->global_vel, p->IT_inf);
			}
			DoLog(LOG_IT, "(r)%d,(%.1f, %.1f),%.1f",p->InsideNO, p->pos.x, p->pos.y,
				p->IT_inf.IT_cycles); 
		}else if(!p->Updated_pos()){
			//没有更新位置时延用上周期估计值
			p->IT_inf.IT_cycles = Max(0.0f, p->IT_inf.IT_cycles-1);
			DoLog(LOG_IT, "(e)%d,(%.1f, %.1f),%.1f",p->InsideNO, p->pos.x, p->pos.y,
				p->IT_inf.IT_cycles);
		}else if(Self.updated_sight_time == situation.CurrentTime || p->original_postime == situation.CurrentTime){
			if(!p->bodyfc_guessed){
				getinterceptioninfo(ballpos, ballvel, p->pos, p->global_vel, p->bodyfacing, p->IT_inf);
			}else{
				getinterceptioninfo(ballpos, ballvel, p->pos, p->global_vel, p->IT_inf);
			}
			DoLog(LOG_IT, "(n)%d,(%.1f, %.1f),%.1f",p->InsideNO, p->pos.x, p->pos.y,
				p->IT_inf.IT_cycles); 
		}else{
			if(!p->bodyfc_guessed){
				getinterceptioninfo(ballpos, ballvel, p->Pos(Self.updated_sight_time), 
					p->Vel(Self.updated_sight_time), p->bodyfacing, p->IT_inf);
			}else{
				getinterceptioninfo(ballpos, ballvel, p->Pos(Self.updated_sight_time),
					p->Vel(Self.updated_sight_time), p->IT_inf);
			}
			p->IT_inf.IT_cycles -= sight_gap;
			DoLog(LOG_IT, "(f)%d,(%.1f, %.1f),%.1f",p->InsideNO, p->pos.x, p->pos.y,
			p->IT_inf.IT_cycles); 
		}
	}

/* sort players by their ability to intercept the ball */
	for(i = 0; i < num_my - 1; i++)
		for ( j = i + 1; j < num_my; j ++){
			if (MyPlayer(MyPlayers_Interception[j]).IT_inf.IT_cycles < MyPlayer(MyPlayers_Interception[i]).IT_inf.IT_cycles){
				Swap(MyPlayers_Interception[j], MyPlayers_Interception[i]);
			}
		}
	
	for(i = 0; i < num_their - 1; i++)
		for ( j = i + 1; j < num_their; j ++){
			if (TheirPlayer(TheirPlayers_Interception[j]).IT_inf.IT_cycles < TheirPlayer(TheirPlayers_Interception[i]).IT_inf.IT_cycles){
				Swap(TheirPlayers_Interception[j], TheirPlayers_Interception[i]);
			}
		}

	situation.most_promising_controller = -1;

	if (num_my > 0){
		my_min_cycles = MyPlayer(MyPlayers_Interception[0]).IT_inf.IT_cycles;
	}else{
		my_min_cycles = InfCycles;
	}

	if(num_their > 0){
		their_min_cycles = TheirPlayer(TheirPlayers_Interception[0]).IT_inf.IT_cycles;
	}else{
		their_min_cycles = InfCycles;
	}
	
	if(Self.IsForward() && Self.pos.x > 0.0f){
		setsmartit(true);
	}else{
		setsmartit(false);
	}
	SetSelfIT();
	smart_self_intercept(ball.pos, ball.global_vel, Self.pos, Self.global_vel, Self.bodyfacing, Self.IT_inf);
	
	self_cycles = Self.IT_inf.IT_cycles;
	
	situation.min_IT_cycles = InfCycles;

	DoLog("min_it_cycles, their%.1f, my%.1f, me%.1f", their_min_cycles, my_min_cycles, self_cycles);
	//判断最有希望截到球的人, 当截球周期相等时,凭离球距离来判断
	float min_cycles = Min(my_min_cycles, Min(their_min_cycles, self_cycles));
	int promising_side;//0-opponent, 1-teammate, 2-self
	if(their_min_cycles == min_cycles){
		if(my_min_cycles > min_cycles && self_cycles > min_cycles){
			promising_side= 0;
		}else{
			float d1,d2,d3;
			d1 = TheirPlayer(TheirPlayers_Interception[0]).pos.dist2(TheirPlayer(TheirPlayers_Interception[0]).IT_inf.IT_point);
			if(my_min_cycles == min_cycles){
				d2 = MyPlayer(MyPlayers_Interception[0]).pos.dist2(MyPlayer(MyPlayers_Interception[0]).IT_inf.IT_point);
			}else{
				d2 = d1+1;
			}
			if(self_cycles = min_cycles){
				d3 = Self.pos.dist2(Self.IT_inf.IT_point);
			}else{
				d3= d1+1;
			}
			if(d1<=d2 && d1<=d3)
				promising_side = 0;
			else if(d2<=d3)
				promising_side = 1;
			else
				promising_side = 2;

		}
	}else if(my_min_cycles== min_cycles){
		if(self_cycles > min_cycles){
			promising_side = 1;
		}else{
			float d1,d2;
			d1 = MyPlayer(MyPlayers_Interception[0]).pos.dist2(MyPlayer(MyPlayers_Interception[0]).IT_inf.IT_point);			
			d2 = Self.pos.dist2(Self.IT_inf.IT_point);
			promising_side = (d1<=d2 ? 1 : 2);			
		}
	}else{
		promising_side = 2;
	}
	if(promising_side == 0){
		if(TheirPlayers_Interception[0] <= SP_team_size){
			situation.most_promising_controller = SP_team_size + TheirPlayers_Interception[0];
		}
		else{
			situation.most_promising_controller = TheirPlayers_Interception[0];
		}

		situation.next_interception_point = TheirPlayer(TheirPlayers_Interception[0]).IT_inf.IT_point;
		situation.min_IT_cycles = TheirPlayer(TheirPlayers_Interception[0]).IT_inf.IT_cycles;
	}else if(promising_side == 1){
		situation.most_promising_controller = MyPlayers_Interception[0];
		situation.next_interception_point = MyPlayer(MyPlayers_Interception[0]).IT_inf.IT_point;
		situation.min_IT_cycles = MyPlayer(MyPlayers_Interception[0]).IT_inf.IT_cycles;
	}else if(promising_side == 2){
		situation.most_promising_controller = Agent::MyNumber;
		situation.next_interception_point = Self.IT_inf.IT_point;
		situation.min_IT_cycles = Self.IT_inf.IT_cycles;
	}
	my_min_cycles = Min(Self.IT_inf.IT_cycles, my_min_cycles);
	situation.Team_Control = calculatecontrol(my_min_cycles, their_min_cycles);
}

IT_mode Interception::intercept(InterceptionInfo& inf){
	Command command;
	IT_mode it_mode = intercept(inf, command);
	Agent::mediator.enroll(command, Action_interception, PriorityA);
	return it_mode;	
}

IT_mode Interception::intercept(InterceptionInfo& inf, Command& command){
	//intercept action
	command.Reset();
	if (inf.IT_is_closeball){
		if (inf.IT_angle == IT_dash_angle){
			command.dash(inf.IT_dashpow);
		}else if(inf.IT_angle == IT_smartstay_angle){
			command.stay(0);
		}else{
			Agent::motion.turn_to(inf.IT_angle, command);
		}
		DoLog(LOG_IT, "closeballinterception");
		return IT_closeball;		
	}
	else{
		if (inf.IT_valid && fabs(NormalizeAngle(inf.IT_angle - Self.bodyfacing)) > 15 - 8*exp(-ball.distance * 0.15f)){
			Agent::motion.turn_to(inf.IT_angle, command);
			return IT_turn;
		}
		else{
			Agent::motion.run(inf.IT_rapidness, command);
			return IT_dash;
		}
	}
}

void Interception::Do_Intercept(InterceptionInfo& IT_info){
	Command command;
	intercept(IT_info, command);	
	Agent::mediator.enroll(command, Action_interception, 2 * PriorityA);
}

bool Interception::SmartInterception(){
	//first decide whether the player should intercept the ball
	//if he is in interception, decide whether he should cancel it

	//the sight information is sufficient to make interception decision
	if (ball.pos_conf < 0.75 || ball.speed_conf < 0.7 || ball.Isforgot()) return false;
	
	//ball is in someone's control, don't be hook up
	if (!situation.BallFree) return false;

	DoLog(LOG_IT, "most promising IT player%d, cycle%.2f at (%.2f %.2f)",situation.most_promising_controller,
		GetPlayer(situation.most_promising_controller).IT_inf.IT_cycles, GetPlayer(situation.most_promising_controller).pos.x, GetPlayer(situation.most_promising_controller).pos.y);
	DoLog(LOG_IT, "My Cycles %.2f", Self.IT_inf.IT_cycles);
	
	// can not get the ball
	if (Self.IT_inf.IT_cycles == InfCycles ) return false;

	float control;
	int num = FieldInfo.Num_MyVisiblePlayers();
	int i;
	Player* p;
	float IT_extra_gap = 2.0f;
//check if there is need for me to intercept that ball
	for(i = 0; i < num; i ++){

		if (MyPlayer_CtrlOfBall(i).Is_goalie 
			|| Agent::MyNumber == MyPlayers_Interception[i]) continue;

		control = calculatecontrol(Self.IT_inf, MyPlayer_CtrlOfBall(i).IT_inf, true);

		//fix by yjy
		if(their_min_cycles <= MyPlayer_CtrlOfBall(i).IT_inf.IT_cycles && Self.IT_inf.IT_cycles < MyPlayer_CtrlOfBall(i).IT_inf.IT_cycles){
			break;
		}else if(their_min_cycles <= Self.IT_inf.IT_cycles && Self.IT_inf.IT_cycles > MyPlayer_CtrlOfBall(i).IT_inf.IT_cycles){
			return false;
		}

		if (control > 0.55f){
		//the player with the best chance of getting the ball should go
			DoLog(LOG_IT, "I have better chance than %d", MyPlayers_Interception[i]);
			break;
		}
		else if (WouldIntercept(situation.MySide, MyPlayers_Interception[i])){
			if (control < 0.45f){
				DoLog(LOG_IT, "%d has a better chance whose cycle is %f", MyPlayers_Interception[i], MyPlayer_CtrlOfBall(i).IT_inf.IT_cycles);
				return false;
			}
			else if (!Is_IT_Priored(Agent::MyNumber, MyPlayers_Interception[i])){
			//is it dangerous
				DoLog(LOG_IT, "%d is equal in chance but it is priored whose cycle is %.2f", MyPlayers_Interception[i], MyPlayer_CtrlOfBall(i).IT_inf.IT_cycles);
				return false;
			}
			else{
				DoLog(LOG_IT, "I am priored than %d", MyPlayers_Interception[i]);
				break;
			}
		}
	}


	bool give_up = false;
	//see if I can get ball from opponent
	num = FieldInfo.Num_TheirVisiblePlayers();
	for(i = 0; i < num; i ++){
		control = calculatecontrol(Self.IT_inf, TheirPlayer_CtrlOfBall(i).IT_inf);
		if(control >= 0.45f){
		//there is great chance
			break;
		}

		if(Self.aggressiveness > 0.5f){
			if (control >= 0.3f)
				break;
		}
		if (WouldIntercept(situation.TheirSide, TheirPlayers_Interception[i])){
				// there is no chance for me to get the ball from opponent
			give_up = true;
			DoLog(LOG_IT, "There is no chance to get ball from %d whose cycles is %.2f", TheirPlayers_Interception[i], TheirPlayer_CtrlOfBall(i).IT_inf.IT_cycles);
			p = &TheirPlayer(TheirPlayers_Interception[i]);
			if(p->Is_goalie){
			}else if(Self.IsForward() && Self.pos.dist(p->IT_inf.IT_point) < p->pos.dist(p->IT_inf.IT_point) + IT_extra_gap){
			}else{
				return false;
			}
		}
	}
	
	//if the ball is definitely out of pitch before i can get there, let it go
	if(!PitchInfo.WithInExpandedField(Self.IT_inf.IT_point)){
		DoLog(LOG_IT, "Out of pitch(%.2f,%.2f)",Self.IT_inf.IT_point.x,  Self.IT_inf.IT_point.y);
		Ray ballray(ball.pos, ball.global_vel.Angle());
		Vector it_point;
		
		if(!PitchInfo.expanded_field.RayIntersection(ballray, it_point)) return false; 

		int t = int(Self.pos.dist(it_point) / Self.IT_inf.IT_rapidness);
		if(ball.global_vel.mod()  * (1 - Exp(ball.speed_decay, (float)t))/(1-ball.speed_decay) < ball.pos.dist(it_point)){
			DoLog("ITPatch:maybe in pitch");
		}else{
			return false;
		}
	}

	//patch for back's dangerous it
	if(Self.IT_inf.IT_cycles > TheirPlayer_CtrlOfBall(i).IT_inf.IT_cycles ){
		if(Self.IsBack()){
			DoLog(LOG_IT, "Dangerous back it");
			if(TheirPlayers_Interception[0] != FieldInfo.TheirPlayers_Close2Me[0]){
				DoLog(LOG_IT, "patch, cancel it for wrong player");
				return false;
			}else{
				Command cmd;
				intercept(Self.IT_inf, cmd);
				if(cmd.GetCMDType() == CMD_turn){
					DoLog(LOG_IT, "patch, cancel it for turn");
					return false;
				}
			}
		}
	}
	if(give_up){
		p = &TheirPlayer(TheirPlayers_Interception[0]);
		if(p->Is_goalie){ 
			DoLog(LOG_IT, "intercept from goalie %.0f-%.0f", p->IT_inf.IT_cycles, Self.IT_inf.IT_cycles);
		}else{
			DoLog(LOG_IT, "intercept from opp%d %.0f-%.0f", TheirPlayers_Interception[0], p->IT_inf.IT_cycles, Self.IT_inf.IT_cycles);
		}
	}
	Do_Intercept(Self.IT_inf);
	return true;
}

bool Interception::Is_IT_Priored(UNum player1, UNum player2){
	if (!MyPlayer(player1).IsRoleKnown()) return false;
	if (!MyPlayer(player2).IsRoleKnown()) return true;
	Vector point1, point2, ballpos;
	point1 = formation.GetFormationPoint(MyPlayer(player1));
	point2 = formation.GetFormationPoint(MyPlayer(player2));

	ballpos = situation.NextControlBallPos();
	return ballpos.dist2(point1) < ballpos.dist2(point2);
}


bool Interception::WouldIntercept(char side, UNum No){
	if (GetPlayer(side, No).Is_goalie){
		return PitchInfo.their_penaltyarea.IsWithin(GetPlayer(side, No).IT_inf.IT_point);
	}
	return true;
}

float Interception::calculatecontrol(InterceptionInfo& myinf, InterceptionInfo& theirinf, bool is_teammate){
	if (myinf.IT_is_closeball && !is_teammate){
		return calculatecontrol(myinf.IT_cycles, (float)int(theirinf.IT_cycles) + 2.0f);
	}
	return calculatecontrol(myinf.IT_cycles, theirinf.IT_cycles);
}

float Interception::calculatecontrol(float my_cycles, float their_cycles){
	if(my_cycles == InfCycles){
		if (their_cycles == InfCycles)
			return 0.5f;
		else
			return 0.0f;
	}
	else if (their_cycles == InfCycles)
		return 1.0f;
	double input[2];
	double control;
	float cycles_gap = (float)fabs(my_cycles - their_cycles), min_cycles = Min(my_cycles, their_cycles);
	input[0] = fabs(my_cycles - their_cycles) /10;
	input[1] = fabs(Min(my_cycles, their_cycles)) / 10;
	ControlBallNet.SimulateNet(&input[0], &control);
	control = Max(control, 0.5);
	
	if (my_cycles <= their_cycles)
		return  (float)control;
	else
		return 1 - (float)control;
}


Player& Interception::MyPlayer_CtrlOfBall(int idx){
	return MyPlayer(MyPlayers_Interception[idx]);
}

Player& Interception::TheirPlayer_CtrlOfBall(int idx){
	DoLog(LOG_SEE,"TheirPlayer_CtrlOfBall(%d) %d",idx,TheirPlayers_Interception[idx]);
	return TheirPlayer(TheirPlayers_Interception[idx]);
}

⌨️ 快捷键说明

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