📄 skill.cpp
字号:
} est_time = player_time; // if ball rolls more, player must go further if(s + penalty > m) l = m; else r = m; }while(r - l > 0.1); } log.Log("(Intercept) Interception point = (%.3f, %.3f)\n", target[0], target[1]); return target;}// just calculate the intercept point, then gotoint Skill::Intercept(float low, float high, float pen){ int est_time, min_time, max_time; Vector3f target = Intercept(0, wm.GetTeamUnum(), low, high, est_time, min_time, max_time, pen); Goto(target, true); return est_time;}salt::Vector3f Skill::GetInterceptPoint(float low, float high, float pen){ int est_time, min_time, max_time; return Intercept(0, wm.GetTeamUnum(), low, high, est_time, min_time, max_time, pen);}// using intercept() is more accurate, but very expensivefloat Skill::InterceptTime(int team, int unum){ Vector3f pos = wm.GetPlayerPosition(team, unum); Vector3f ballpos = wm.GetBallStopPosition(); pos[2] = 0.0; ballpos[2] = 0.0; return (pos-ballpos).Length();}// consider home players only// TODO: if two people are very close, one(who is more distant to his BSP) should go awaybool Skill::Interceptable(){ int player_count = 11; float time = InterceptTime(0, wm.GetTeamUnum()); for(int i = 1; i <= player_count; i++) if (InterceptTime(0, i) < time - 0.1) return false; return true;}void Skill::Dribble(float angle){ Vector3f mypos = wm.GetMyPosition(); Vector3f ballpos = wm.GetBallPosition(); ballpos[2] = 0.0; Vector3f intpos = GetInterceptPoint(angle-5.0, angle+5.0, 0.0); Goto(intpos); Vector3f driveline(gCos(gDegToRad(angle)), gSin(gDegToRad(angle)), 0.0); Vector3f pos = ballpos + driveline; // well, just try to kick... since vision error is present, 0.5 is safer bool safe = true; float dist = -100.0; float min_disttoline = 1000.0; for(int enemy = 1; enemy <= 11; enemy++) { Vector3f epos = wm.GetPlayerPosition(1, enemy); Point ep = MakePoint(epos); Point ballp = MakePoint(ballpos); Point p = MakePoint(pos); Point dummy; float dist = GetProjectionDistance(ballp, p, ep); float disttoline = fabs(DistanceToLine(ep, ballp, p, dummy)); if(dist > 0.0 && disttoline < min_disttoline) min_disttoline = disttoline; if(dist > -0.3 && dist < 5.0 && disttoline < 2.0) safe = false; // modified } // kickable if((wm.GetMyPosition() - wm.GetBallPosition()).Length() < 0.5) { bool oktodribble = false; if(ballpos[0] < 30.0) { if(ballpos[0] - wm.GetMyPosition()[0] > 0.3 || situation.Dangerous() && ballpos[0] > wm.GetMyPosition()[0]) oktodribble = true; } else { if(ballpos[1] > 3.6) { if(wm.GetMyPosition()[1] > ballpos[1] + 0.3) oktodribble = true; } else if(ballpos[1] < -3.6) { if(wm.GetMyPosition()[1] < ballpos[1] - 0.3) oktodribble = true; } else oktodribble = true; } if(oktodribble) { if(safe) agent.Kick(0, 5); else { // TODO: if i'm the first one, wait, otherwise, kick // current version: read the distance to centerpoint float shoottarget; bool canshoot = false; if(situation.OkToShoot(0, wm.GetTeamUnum(), shoottarget)) { float center = 0.0f; if(mypos[1] > 3.0) center = -1.2; else if(mypos[1] < -3.0) center = 1.2; canshoot = true; if(fabs(shoottarget-center) > 2.0 && situation.GetStoppedTime() < 0.5) canshoot = false; if(canshoot) { Vector3f centerpos(wm.GetFieldLength()/2.0, 0.0, 0.0); float dist = (ballpos-centerpos).Length(); if(dist > 18.1) agent.Kick(30, 100); else agent.Kick(30, dist*5.5); // don't kick with too much power! } } else if(!canshoot) { if(ballpos[0] < 20.0) agent.Kick(30, 100); // kick to them quickly ^_* else agent.Kick(50, 30); // near goal, should attention } } } }}void Skill::Pass(float dist){ float angle = decision.GetPassAngle(); Intercept(angle - 5.0, angle + 5.0, 0.0); // kick high? bool high = false; Vector3f mypos = wm.GetMyPosition(); Vector3f ballpos = wm.GetBallPosition(); Vector3f driveline = ballpos - mypos; driveline.Normalize(); Vector3f pos = ballpos + driveline * dist; int i; for(i = 1; i <= 11; i++) { Vector3f epos = wm.GetPlayerPosition(1, i); Point ep = MakePoint(epos); Point p = MakePoint(pos); Point ballp = MakePoint(ballpos); Point dummy; float d = GetProjectionDistance(ballp, p, ep); float dline = fabs(DistanceToLine(ep, ballp, p, dummy)); if(d > 0 && d < dist && dline < 0.4) high = true; } if(high) { if(dist > 18.1) dist = 18.1; agent.Kick(30, dist * 5.5); } else { if(dist > 25.0) dist = 25.0; agent.Kick(0, dist * 4.0); }}void Skill::Shoot(){ Vector3f mypos = wm.GetMyPosition(); Vector3f ballpos = wm.GetBallPosition(); float shoottarget; if((ballpos-mypos).Length() < 1.0) // originally 1.0 { bool canshoot = true; if(situation.OkToShoot(0, wm.GetTeamUnum(), shoottarget)) { // this is time to adjust to get better scoring chance // 2.0 could be changed according to oppmodel // even if dangerous, don't shoot... float center = 0.0f; if(mypos[1] > 3.0) center = -0.8; else if(mypos[1] < -3.0) center = 0.8; if(fabs(shoottarget-center) > 2.0 && situation.GetStoppedTime() < 0.5) { log.Log("(Shoot) cannot 1\n"); canshoot = false; } // wrong direction if(ballpos[1] > wm.GetGoalWidth()/2.0 && mypos[1] < ballpos[1] + 0.15) { log.Log("(Shoot) cannot 2\n"); canshoot = false; } if(ballpos[1] < -wm.GetGoalWidth()/2.0 && mypos[1] > ballpos[1] - 0.15) { log.Log("(Shoot) cannt 3\n"); canshoot = false; } } if(canshoot) { log.Log("(Shoot) can shoot, target=%.3f, mypos=(%.3f,%.3f), ballpos=(%.3f,%.3f)\n", mypos[0], mypos[1], ballpos[0], ballpos[1]); agent.Kick(0,100); //TODO: enemy in front? } } // the ball is moving! go to the interception point float center; if(mypos[1] > 3.0) center = -0.8; else if(mypos[1] < -3.0) center = 0.8; float dx = wm.GetFieldLength()/2.0 - mypos[0]; float dy1 = center - 2.0 - mypos[1]; float dy2 = center + 2.0 - mypos[1]; float angle1 = gRadToDeg(gArcTan2(dy1, dx)); float angle2 = gRadToDeg(gArcTan2(dy2, dx)); Vector3f intp = GetInterceptPoint(angle1, angle2); Goto(intp);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -