📄 score_bms.c
字号:
//LOG_DAN(0, << "upper secure arg is " << upper_secure_arg); test_dirs[0] = Tools::get_angle_between_null_2PI(upper_secure_arg - delta_ang * 3.0); test_dirs[1] = Tools::get_angle_between_null_2PI(upper_secure_arg - delta_ang * 2.0); test_dirs[2] = Tools::get_angle_between_null_2PI(upper_secure_arg - delta_ang * 4.0); test_dirs[3] = Tools::get_angle_between_null_2PI(upper_secure_arg - delta_ang * 1.0); test_dirs[4] = Tools::get_angle_between_null_2PI(upper_secure_arg - delta_ang * 5.0); test_dirs[7] = Tools::get_angle_between_null_2PI(upper_secure_arg); test_dirs[8] = Tools::get_angle_between_null_2PI(upper_secure_arg - delta_ang * 6.0); if (delta_ang > DEG2RAD(4.0)) { test_dirs[5] = Tools::get_angle_between_null_2PI(upper_secure_arg - DEG2RAD(2.0)); test_dirs[6] = Tools::get_angle_between_null_2PI(upper_secure_arg - delta_ang * 6.0 + DEG2RAD(2.0)); } else { test_dirs[5] = Tools::get_angle_between_null_2PI(upper_secure_arg - delta_ang/2.0); test_dirs[6] = Tools::get_angle_between_null_2PI(upper_secure_arg - delta_ang * 6.0 + delta_ang/2.0); } Vector st; for (int i = 0; i < nr_of_targets; ++i) { st.init_polar(1.0, test_dirs[i]); st = (1.0/st.x) * st; //st /= (st.x); DAS IST FALSCH(geht so nicht, siehe Implementuerung von Vector test_targets[i] = (ServerOptions::pitch_length/2.0 - WSinfo::ball->pos.x) * st + WSinfo::ball->pos; }}void Score::consider_special_cases(int goalie_age, int goalie_vel_age, Vector goalie_vel, Value &goalie_initial_size, Vector &goalie_pos, PPlayer goalie) { if (goalie_vel_age == 0) { //if (goalie_vel.norm() > 0.1) { LOG_DAN(0, << "goalie_pos um " << goalie_vel << "verschoben"); goalie_pos = goalie_pos + goalie_vel; //if (goalie_initial_size >= 0.3) goalie_initial_size -= 0.3; //else goalie_initial_size = 0.0; //} } if (fabs(WSinfo::ball->vel.y) > 1.0) { LOG_DAN(0, << "ball has high y-velocity, assume that goalie moves!"); goalie_initial_size += 0.4; }#if 0 // ridi goalshot if (goalie_age <= 1) { if ((goalie_pos - WSinfo::me->pos).norm() < 5.0) { LOG_DAN(0, << " goalie too close, reducing size to 0"); goalie_initial_size = 0.0; } }#endif }int Score::select_best_kick(int *kick_possible, int nr_of_targets) { int all_possible = 1; for (int i = 0; i < nr_of_targets; ++i) { if (kick_possible[i] == 0) { all_possible = 0; break; } } if (all_possible) return 0; int left_side = 0, right_side = 0; for (int i = 1; i < nr_of_targets; ++i) { if (kick_possible[i]) { if (i%2 == 1) ++left_side; else right_side++; } } if (left_side == right_side) { if (WSinfo::ws->time % 2 == 0) { ++right_side; } else { ++left_side; } } if (left_side > right_side) { if (kick_possible[1] && kick_possible[3]) return 3; if (kick_possible[5]) return 5; else { for (int j = 0; j < nr_of_targets; ++j) { if ((kick_possible[j]) && (j%2 == 1)) return j; } } } else if (left_side < right_side) { if (kick_possible[2] && kick_possible[4]) return 4; if (kick_possible[6]) return 6; else { for (int j = 0; j < nr_of_targets; ++j) { if ((kick_possible[j]) && (j%2 == 0)) return j; } } } return -1;}Value Score::player_action_radius_at_time(int time, PPlayer player, Value player_dist_to_ball, int player_handicap) { //used for learning, otherwise players try to shoot through static defenders return 1.1; int time_L = time - player_handicap; if (player_dist_to_ball < 3.0) { if (time_L <= 2) { return 0.0 + player->kick_radius; } else { return player->speed_max * (time_L-2) * 0.8 + player->kick_radius; } } else { if (time_L <= 1) { return 0.0 + player->kick_radius; } else { return player->speed_max * (time_L-1) * 0.8 + player->kick_radius; } }}int Score::intercept_opponents(Value direction, Value b_v, int max_steps) { WSpset pset = WSinfo::valid_opponents; pset.keep_players_in_cone(WSinfo::ball->pos, ANGLE(direction-DEG2RAD(20)), ANGLE(direction+DEG2RAD(20))); Vector player_pos, b_pos, b_vel, ball_vel; Value player_dist_to_ball, player_action_radius; ball_vel.init_polar(b_v, direction); for (int i = 0; i < pset.num; ++i) { if (pset[i]->number == WSinfo::ws->his_goalie_number) continue; player_pos = pset[i]->pos; b_pos = WSinfo::ball->pos; b_vel = ball_vel; player_dist_to_ball = (pset[i]->pos - WSinfo::ball->pos).norm(); for (int j = 1; j < 12; ++j) { b_pos += b_vel; b_vel *= ServerOptions::ball_decay; player_action_radius = player_action_radius_at_time(j, pset[i], player_dist_to_ball, 0);//0.4 if ((b_pos - player_pos).norm() < player_action_radius) { if (pset[i]->number > 0) return pset[i]->number; else return 1; } } } return 0;}Value Score::goalie_action_radius_at_time(int time, Value goalie_size, int goalie_handicap) { int time_L = time - goalie_handicap; if (time_L < 0) return 0.0; switch (time_L) { case 0: return 0.0; case 1: return goalie_size; case 2: return 0.6 + goalie_size; case 3: return 1.4 + goalie_size; case 4: return 2.4 + goalie_size; default: if (time_L < 0) return 0.0; else return 2.4 + 1.0 * (time_L - 4) + goalie_size; } }/* Berechnet den Schnittpunkt zweier Geraden */Vector Score::intersection_point(Vector p1, Vector steigung1, Vector p2, Vector steigung2) { double x, y, m1, m2; if ((steigung1.x == 0) || (steigung2.x == 0)) { if (fabs(steigung1.x) < 0.00001) { return point_on_line(steigung2, p2, p1.x); } else if (fabs(steigung1.x) < 0.00001) { return point_on_line(steigung1, p1, p2.x); } } m1 = steigung1.y/steigung1.x; m2 = steigung2.y/steigung2.x; if (m1 == m2) return Vector(-51.5, 0); x = (p2.y - p1.y + p1.x*m1 - p2.x*m2) / (m1-m2); y = (x-p1.x)*m1 + p1.y; return Vector (x, y);}/* Berechnet die y-Koordinate Punktes auf der Linie, der die x-Koordinate x hat */Vector Score::point_on_line(Vector steigung, Vector line_point, Value x) { //steigung.normalize(); steigung = (1.0/steigung.x) * steigung; if (steigung.x > 0) { return (x - line_point.x) * steigung + line_point; } if (steigung.x < 0) { return (line_point.x - x) * steigung + line_point; } // Zur Sicherheit, duerfte aber nie eintreten return line_point;} /* point_on_line */int Score::intercept_goalie(Vector ball_pos, Vector ball_vel, Vector goalie_pos, Value goalie_size) { if (ball_vel.x < 0.0) return 1; if (ball_vel.norm() < 0.5) return 1; LOG_DAN(0, << "goalie_initial_size ist " << goalshot_param1); Vector b_pos = ball_pos; Vector b_vel = ball_vel; Value goal_x = ServerOptions::pitch_length/2.0; Value goalie_action_radius; int time = 1; bool wrong_angle = false; for (int i = 1; i < 50; ++i) { b_pos += b_vel; b_vel *= ServerOptions::ball_decay; goalie_action_radius = goalie_action_radius_at_time(time, goalie_size, 0);//0.4 if (wrong_angle) goalie_action_radius -= 0.3; //LOG_DAN(0, << _2D << C2D(goalie_pos.x, goalie_pos.y, goalie_action_radius + 2.0, "#0000ff")); //LOG_DAN(0, << _2D << C2D(b_pos.x, b_pos.y, 1, "00ff00")); if (b_pos.x > goal_x + 0.3) { //LOG_DAN(0, << "time is " << time); return -time; } else if (((b_pos - goalie_pos).norm() - goalie_action_radius < 2.0) && wrong_angle) {//(time != i)) { return 1; } else if (((b_pos - goalie_pos).norm() - goalie_action_radius < 2.0) && !wrong_angle) {//(time == i)) { if (goalie_needs_turn_for_intercept(time, ball_pos, ball_vel, b_pos, b_vel, goalie_size)) { //time--; wrong_angle = true; } else return 1; } ++time; } return 1;}bool Score::goalie_needs_turn_for_intercept(int time, Vector initial_ball_pos, Vector initial_ball_vel, Vector b_pos, Vector b_vel, Value goalie_size) { //test if goalie has a bad angle for the intercept#if 0 // ridi 22.6.03 : replaced by new access to goalie WSpset alive_opps = WSinfo::alive_opponents; PPlayer goalie = alive_opps.get_player_by_number(WSinfo::ws->his_goalie_number);#endif PPlayer goalie =WSinfo::his_goalie; if (goalie == NULL) return 0; if (goalie->age > 1) return 0; Vector goalie_ang; goalie_ang.init_polar(1.0, goalie->ang); Vector intersection = intersection_point(goalie->pos, goalie_ang, initial_ball_pos, initial_ball_vel); LOG_DAN(0, << _2D << C2D(intersection.x, intersection.y, 1, "ff0000")); //ridi: not used: Vector op_to_intersection = intersection - initial_ball_pos; Value dist = (intersection-initial_ball_pos).norm(); Vector ball_in_goal = Vector(point_on_line(initial_ball_vel, initial_ball_pos,ServerOptions::pitch_length/2.0)); //LOG_DAN(0, "Ball ueberschreitet Torlinie an " << ball_in_goal.x << " " << ball_in_goal.y); if (dist - 2.0 > (ball_in_goal - initial_ball_pos).norm() && ((b_pos - goalie->pos).norm() > 2.5)) { LOG_DAN(0, "Schnittpunkt zu weit entfernt!"); return 1; //--time; } else { int time_L = time; Vector b_pos_L = b_pos; Vector b_vel_L = b_vel; for (int j = 0; j < 10; ++j) { if ((b_pos_L - initial_ball_pos).norm() > dist - 2.0) { Value goalie_rad = goalie_action_radius_at_time(time_L, goalie_size, 0); Value goalie_rad2 = goalie_action_radius_at_time(time_L+1, goalie_size, 0); Vector g_pos = intersection-goalie->pos; Vector g_pos2 = g_pos; g_pos.normalize(goalie_rad); g_pos += goalie->pos; g_pos2.normalize(goalie_rad2); g_pos2 += goalie->pos; LOG_DAN(0, << _2D << C2D(b_pos_L.x, b_pos_L.y, 1, "ff00ff")); if ((goalie_rad + 2.0 < (intersection-goalie->pos).norm()) && !is_pos_in_quadrangle(b_pos_L, goalie->pos, g_pos, 4.0) && (b_pos_L.distance(g_pos) > 2.2) && !is_pos_in_quadrangle(b_pos_L+b_vel_L, goalie->pos, g_pos2, 4.0) && (b_pos_L.distance(g_pos2) > 2.2) && ((b_pos-goalie->pos).norm() > 2.5) && ((goalie_rad*(intersection-goalie->pos)+goalie->pos - b_pos_L).norm() > 2.5)) { LOG_DAN(0, << "goalie has bad angle for intercept => needs one extra step"); LOG_DAN(0, << _2D << C2D(g_pos.x, g_pos.y, 1, "ffff00")); //--time; return 1; //break; } else return 0; } b_pos_L += b_vel_L; b_vel_L *= ServerOptions::ball_decay; ++time_L; } return 0; }}bool Score::is_pos_in_quadrangle(Vector pos, Vector p1, Vector p2, Vector p3, Vector p4) { if ( Tools::point_in_triangle(pos, p1,p2,p3) || Tools::point_in_triangle(pos, p1,p3,p4) ) { return true; } return false;}bool Score::is_pos_in_quadrangle(Vector pos, Vector p1, Vector p2, Value width) { Vector tmp= p2-p1; Vector norm; norm.x= -tmp.y; norm.y= tmp.x; norm.normalize(0.5*width); Vector g1= p1+ norm; Vector g2= p1- norm; Vector g3= p2- norm; Vector g4= p2+ norm; return is_pos_in_quadrangle(pos,g1,g2,g3,g4);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -