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