📄 pass.cpp
字号:
return counter_idx;
}
if (counter_idx == -1){
for(i = num_routes_considered; i > clockwise_idx; i --){
if (IsExplored(i)){
counter_idx = i;
break;
}
}
DoLog(LOG_PASS, "clockwise_idx %d counter %d", clockwise_idx, counter_idx);
if (counter_idx == -1)
return clockwise_idx;
}
return fabs(NormalizeAngle(Routes_considered[routeidx] - Routes_considered[clockwise_idx]))
< fabs(NormalizeAngle(Routes_considered[routeidx] - Routes_considered[counter_idx])) ?
clockwise_idx : counter_idx;
}
bool Pass::IsExplored(int idx){
if (idx < 0 || idx >= num_routes_considered) return false;
return num_controllers[idx].time == situation.CurrentTime;
}
bool Pass::Explore(int routeidx){
if (routeidx < 0 || routeidx >= num_routes_considered) return false;
Vector point;
ctrl_list.cleanup();
ballcourse = Ray(ball.pos, Routes_considered[routeidx]);
//set pitch constraint
if (fieldinfo.shrinked_field.RayIntersection(ballcourse, point)){
ctrl_list.GetData(ctrl_list.Head()) = ballcourse.DistanceFromOrigin(point);
}
else{
//max distances
ctrl_list.GetData(ctrl_list.Head()) = SP_pitch_diameter;
}
ballcourse = Ray(0, Routes_considered[routeidx]);
ballcourse.Normalize();
//first see if there is some information that can foster the search
int nearest_explored_route = GetNearestExploredRoute(routeidx), i, begin;
//add controllers in the nearest route first
if (nearest_explored_route != -1){
begin = ctrl_list.Head();
for(i = 0; i < num_controllers[nearest_explored_route].data; i ++){
AddtoCtrlList(controllers_of_line[nearest_explored_route][i], begin);
}
}
begin = ctrl_list.Head();
for(i = 0; i < num_players_considered; i ++){
AddtoCtrlList(i, begin);
}
num_controllers[routeidx].data = 0;
num_controllers[routeidx].time = situation.CurrentTime;
int q = ctrl_list.ActualHead();
while(ctrl_list.IsValid(q)){
if (num_controllers[routeidx].data > CP_max_considerd_pass_players)
break;
deliminator[routeidx][num_controllers[routeidx].data] = ctrl_list.GetData(q);
controllers_of_line[routeidx][num_controllers[routeidx].data ++] = q;
q = ctrl_list.Next(q);
}
GetGT_speedinfo(routeidx);
return true;
}
bool Pass::GetGT_speedinfo(int routeidx){
if (!IsExplored(routeidx))
return false;
Vector point;
float min_gt_speed = 0.0f, peak_point;
int peakpoint_considered_idx = -1, i, j, num;
num = num_controllers[routeidx].data;
/*DoLog(LOG_PASS, "angle %.2f controllers %d", Routes_considered[routeidx], num);
char string[1000];
int len = 0;
string[0] = 0;
for(i = 0; i < num; i ++){
len += sprintf(string + len, "%d %.2f ", Players_considered[controllers_of_line[routeidx][i]],
deliminator[routeidx][i]);
}
DoLog(LOG_PASS, string);*/
for(i = 0; i < num; i++){
if (GetPlayer_considered(controllers_of_line[routeidx][i]).IsMyside()){
for(j = peakpoint_considered_idx + 1; j < i; j ++){
if(i == 0){
//impossible branch
break;
}
if (Players_considered[controllers_of_line[routeidx][j]] == MyNumber)
continue;
point = GetPlayer_considered(controllers_of_line[routeidx][j]).rel_pos_2_ball.Rotate(- Routes_considered[routeidx]);
peak_point = calc_peakpoint(point);
if(peak_point < deliminator[routeidx][i - 1]){
min_gt_speed = Max(calc_spottingspeed(point, peak_point), min_gt_speed);
}
if (min_gt_speed >= SP_ball_speed_max)
break;
}
if (min_gt_speed >= SP_ball_speed_max)
break;
point = GetPlayer_considered(controllers_of_line[routeidx][i]).rel_pos_2_ball.Rotate(- Routes_considered[routeidx]);
min_gt_speed = Max(calc_spottingspeed(point, deliminator[routeidx][i - 1]),
min_gt_speed);
if (min_gt_speed >= SP_ball_speed_max)
break;
speed_inf[routeidx][i] = min_gt_speed;
peak_point = calc_peakpoint(point);
speed_sup[routeidx][i] = 0.0f;
if (peak_point < deliminator[routeidx][i]){
speed_sup[routeidx][i] = calc_spottingspeed(point, peak_point);
}
speed_sup[routeidx][i] = Max(calc_spottingspeed(point, deliminator[routeidx][i])
, speed_sup[routeidx][i]);
min_gt_speed = Max(min_gt_speed, speed_sup[routeidx][i]);
speed_sup[routeidx][i] = calc_spottingspeed(point, deliminator[routeidx][i]);
speed_sup[routeidx][i] = Min(speed_sup[routeidx][i], SP_ball_speed_max);
peakpoint_considered_idx = i;
//add passinfo
CalcPassinfos(speed_inf[routeidx][i], speed_sup[routeidx][i], Routes_considered[routeidx],
Players_considered[controllers_of_line[routeidx][i]]);
if (min_gt_speed >= SP_ball_speed_max)
break;
}
}
return true;
}
bool Pass::AddtoCtrlList(int p, int& begin){
float t;
int q = begin;
//find insert point
if (!ctrl_list.IsValid(q)){
DoLog(LOG_PASS, "bug q not valid");
return false;
}
while(ctrl_list.IsValid(ctrl_list.Next(q))){
if (ctrl_list.Next(q) > p)
break;
q = ctrl_list.Next(q);
}
begin = q;
if (q == p){
return false;
}
int q_bk = q;
if (!ctrl_list.IsHead(q)){
t = getdeliminator(ballcourse, q, p);
if (t >= ctrl_list.GetElement(q).data || t < 1.0f){
return false;
}
}
//add to the list
ctrl_list.Insert(q, p);
begin = p;
//adjust the list
bool first_run = true;
while(ctrl_list.IsValid(q) && !ctrl_list.IsHead(q)){
if (!first_run){
t = getdeliminator(ballcourse, q, p);
}
else{
first_run = false;
}
if ((ctrl_list.IsHead(ctrl_list.Prev(q)) && t > 0) || t > ctrl_list.GetData(ctrl_list.Prev(q))){
ctrl_list.GetData(q) = t;
break;
}
if (ctrl_list.IsHead(ctrl_list.Prev(q)) && t <= 0){
DoLog(LOG_PASS, "deleter %d %.2f at (%.2f %.2f) ", Players_considered[p], t, GetPlayer_considered(p).rel_pos_2_ball.x,
GetPlayer_considered(p).rel_pos_2_ball.y);
DoLog(LOG_PASS, "pline (%.2f %.2f %.2f) deletee %d", Pline(p, q).A, Pline(p, q).B, Pline(p, q).C, Players_considered[q]);
}
float u = ballcourse.intersection(Pline(p, q_bk));
ctrl_list.Delete(q);
q = ctrl_list.Prev(p);
}
q = ctrl_list.Next(p);
while(ctrl_list.IsValid(q)){
t = getdeliminator(ballcourse, q, p);
if(t < ctrl_list.GetData(q) && t > 0.0f){
ctrl_list.GetData(p) = t;
break;
}
ctrl_list.Delete(q);
q = ctrl_list.Next(p);
}
if (ctrl_list.IsTail(p)){
// p is the tail
ctrl_list.GetData(p) = ctrl_list.GetData(ctrl_list.Head());
}
return true;
}
bool Pass::CalcPassinfos(float min_speed, float max_speed, AngleDeg passangle, UNum No){
if (max_speed - min_speed < 0.2f)
return false;
if (!IsMyPlayer(No))
return false;
if (min_speed >= CP_impossible_speed)
return false;
float weight = PASSWeightByDistance(MyPlayer(No).balldist);
AddPassInfo(No, NormalizeAngle(passangle), min_speed*(1 - weight) + max_speed * weight, true);
int num_speed_divisions = int((max_speed - min_speed) / 0.4f);
for (int j = 0; j < num_speed_divisions; j ++){
AddPassInfo(No, passangle, min_speed + (max_speed - min_speed) * (j + 1) / (num_speed_divisions + 1), true);
}
return true;
}
float Pass::getdeliminator(Ray& ballcourse, int idx1, int idx2){
if (idx1 < 0 || idx1 > num_players_considered || idx2 < 0 || idx2 > num_players_considered)
return SP_pitch_diameter;
float t = ballcourse.intersection(Pline(idx1, idx2));
if(fabs(t) < 0){
Line line(ballcourse);
if (line.dist2(GetPlayer_considered(idx1).pos) < line.dist2(GetPlayer_considered(idx2).pos)){
return SP_pitch_diameter;
}
else{
return 0;
}
}
return t;
}
void Pass::LogPass(float angle){
int routeidx = -1;
float min_angle_gap = 720.0f, angle_gap;
for(int i = 0; i < num_routes_considered; i ++){
angle_gap = (float)fabs(NormalizeAngle(angle - Routes_considered[i]));
if (angle_gap < min_angle_gap){
routeidx = i;
min_angle_gap = angle_gap;
}
}
if (routeidx == -1)
return;
DoLog(LOG_PASS, "angle %.2f controllers %d", Routes_considered[routeidx], num_controllers[routeidx].data);
char string[1000];
int len = 0;
string[0] = 0;
for(i = 0; i < num_controllers[routeidx].data; i ++){
len += sprintf(string + len, "%d %.2f ", Players_considered[controllers_of_line[routeidx][i]],
deliminator[routeidx][i]);
}
DoLog(LOG_PASS, string);
Vector point;
float peak_point;
for(i = 0; i < num_controllers[routeidx].data; i ++){
if (GetPlayer_considered(controllers_of_line[routeidx][i]).IsMyside()){
point = GetPlayer_considered(controllers_of_line[routeidx][i]).rel_pos_2_ball.Rotate(- Routes_considered[routeidx]);
peak_point = calc_peakpoint(point);
DoLog(LOG_PASS, "pass to %d spd(%.2f %.2f) (d %.2f peak %.2f) point(%.2f %.2f)", Players_considered[controllers_of_line[routeidx][i]], speed_inf[routeidx][i], speed_sup[routeidx][i]
,deliminator[routeidx][i], peak_point, point.x, point.y);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -