bool Tackler::MayDangerousIfTackle(const PlayerState & tackler, const WorldState & world_state) { if (tackler.GetTackleProb(false) < FLOAT_EPS && tackler.GetTackleProb(true) < FLOAT_EPS) { //不可铲 return false; } const Vector tackler_pos = tackler.GetPos(); const Vector ball_pos = world_state.GetBall().GetPos(); const Vector ball_2_tackler = ball_pos - tackler_pos; const double ball_dist2 = ball_2_tackler.Mod2(); const AngleDeg ball_dir = ball_2_tackler.Dir(); for (unsigned i = 0; i < world_state.GetPlayerList().size(); ++i) { const PlayerState & opp = *world_state.GetPlayerList()[i]; if (!opp.IsAlive()) continue; //dead if (opp.GetUnum() * tackler.GetUnum() > 0) continue; //not opp if (opp.IsIdling()) continue; //idling if (!opp.IsKickable()) continue; //not kickable //cond. 1. opp no dashing -- 无从知晓,这里认为对手一定会dash //cond. 2. ball near -- 球离自己更近,不构成危险情况 Vector opp_2_tackler = opp.GetPos() - tackler_pos; if (opp_2_tackler.Mod2() > ball_dist2) continue; //cond. 3. behind or big y_diff -- 对手在自己与球连线方向上在自己身后或错开位置太大,不构成危险情况 opp_2_tackler = opp_2_tackler.Rotate(-ball_dir); if (opp_2_tackler.X() < 0.0 || std::fabs( opp_2_tackler.Y() ) > opp.GetPlayerSize() + tackler.GetPlayerSize()) continue; //cond. 4. over body_diff -- 对手身体角度跟自己与球连线方向的夹角大于90度,不构成危险情况 AngleDeg body_diff = std::fabs( GetNormalizeAngleDeg( opp.GetBodyDir() - ball_dir ) ); if (body_diff > 90.0) continue; return true; } return false; }
void BehaviorPassPlanner::Plan(std::list<ActiveBehavior> & behavior_list) { std::cout<<"Inside pass plan"<<std::endl; if (!mSelfState.IsKickable()) return; const std::vector<Unum> & tm2ball = mPositionInfo.GetCloseTeammateToTeammate(mSelfState.GetUnum()); Unum _opp = mStrategy.GetFastestOpp(); if (!_opp) return; PlayerState oppState = mWorldState.GetOpponent( _opp ); bool oppClose = oppState.IsKickable()|| oppState.GetTackleProb(true) > 0.65 ; for (uint i = 0; i < tm2ball.size(); ++i) { ActiveBehavior pass(mAgent, BT_Pass); pass.mTarget = mWorldState.GetTeammate(tm2ball[i]).GetPredictedPos(); if(mWorldState.GetTeammate(tm2ball[i]).IsGoalie()){ continue; } Vector rel_target = pass.mTarget - mBallState.GetPos(); const std::vector<Unum> & opp2tm = mPositionInfo.GetCloseOpponentToTeammate(tm2ball[i]); AngleDeg min_differ = HUGE_VALUE; for (uint j = 0; j < opp2tm.size(); ++j) { Vector rel_pos = mWorldState.GetOpponent(opp2tm[j]).GetPos() - mBallState.GetPos(); if (rel_pos.Mod() > rel_target.Mod() + 3.0) continue; AngleDeg differ = GetAngleDegDiffer(rel_target.Dir(), rel_pos.Dir()); if (differ < min_differ) { min_differ = differ; } } if (min_differ < 10.0) continue; pass.mEvaluation = Evaluation::instance().EvaluatePosition(pass.mTarget, true); pass.mAngle = (pass.mTarget - mSelfState.GetPos()).Dir(); pass.mKickSpeed = ServerParam::instance().GetBallSpeed(5, pass.mTarget.Dist(mBallState.GetPos())); pass.mKickSpeed = MinMax(2.0, pass.mKickSpeed, Kicker::instance().GetMaxSpeed(mAgent , pass.mAngle ,3 )); if(oppClose){//in oppnent control, clear it pass.mDetailType = BDT_Pass_Clear; } else pass.mDetailType = BDT_Pass_Direct; mActiveBehaviorList.push_back(pass); } if (!mActiveBehaviorList.empty()) { mActiveBehaviorList.sort(std::greater<ActiveBehavior>()); if(mActiveBehaviorList.front().mDetailType == BDT_Pass_Clear){ mActiveBehaviorList.front().mEvaluation = 1.0 + FLOAT_EPS; } behavior_list.push_back(mActiveBehaviorList.front()); } else { //如果此周期没有好的动作 if (mAgent.IsLastActiveBehaviorInActOf(BT_Pass)) { ActiveBehavior pass(mAgent, BT_Pass, BDT_Pass_Direct); pass.mTarget = mAgent.GetLastActiveBehaviorInAct()->mTarget; //行为保持 pass.mEvaluation = Evaluation::instance().EvaluatePosition(pass.mTarget, true); pass.mKickSpeed = ServerParam::instance().GetBallSpeed(5 + random() % 6, pass.mTarget.Dist(mBallState.GetPos())); pass.mKickSpeed = MinMax(2.0, pass.mKickSpeed, ServerParam::instance().ballSpeedMax()); behavior_list.push_back(pass); } if(oppClose){ Vector p; BallState SimBall = mBallState; int MinTmInter = HUGE_VALUE, MinOppInter = HUGE_VALUE, MinTm; Vector MinTmPos; for(AngleDeg dir = -45 ; dir <= 45 ; dir += 2.5){ if(!Tackler::instance().CanTackleToDir(mAgent,dir)){ SimBall.UpdateVel(Polar2Vector(Kicker::instance().GetMaxSpeed(mAgent,mSelfState.GetBodyDir() + dir,1),mSelfState.GetBodyDir() + dir),0,1.0); } else SimBall.UpdateVel(Polar2Vector(Max(Tackler::instance().GetBallVelAfterTackle(mAgent,dir).Mod(), Kicker::instance().GetMaxSpeed(mAgent,mSelfState.GetBodyDir() + dir,1)),mSelfState.GetBodyDir() + dir),0,1.0); for(int i = 2 ; i <= 11 ; i ++){ if(fabs((mWorldState.GetTeammate(i).GetPos() - mSelfState.GetPos()).Dir() - dir) > 45 ){ continue; } if(!mWorldState.GetPlayer(i).IsAlive()){continue;} PlayerInterceptInfo* a = mInterceptInfo.GetPlayerInterceptInfo(i); mInterceptInfo.CalcTightInterception(SimBall,a,true); if(MinTmInter > (*a).mMinCycle){ MinTm= i; MinTmInter = (*a).mMinCycle; MinTmPos = (*a).mInterPos; } } for(int i = 1 ; i <= 11 ; i++){ if(fabs((mWorldState.GetOpponent(i).GetPos() - mSelfState.GetPos()).Dir() - dir) > 45 ){ continue; } PlayerInterceptInfo* a = mInterceptInfo.GetPlayerInterceptInfo(-i); mInterceptInfo.CalcTightInterception(SimBall,a,true); if(MinOppInter > (*a).mMinCycle){ MinOppInter = (*a).mMinCycle; } } if(MinOppInter > MinTmInter){ Ray a(mSelfState.GetPos() , mSelfState.GetBodyDir() + dir); Line c(ServerParam::instance().ourLeftGoalPost(),ServerParam::instance().ourRightGoalPost()); c.Intersection(a,p); if( p.Y() < ServerParam::instance().ourPenaltyArea().Top() || p.Y() > ServerParam::instance().ourPenaltyArea().Bottom()){ ActiveBehavior pass(mAgent , BT_Pass , BDT_Pass_Clear); pass.mTarget = MinTmPos; pass.mEvaluation = 1.0 + FLOAT_EPS; pass.mAngle = mSelfState.GetBodyDir() + dir; mActiveBehaviorList.push_back(pass); } } } if (!mActiveBehaviorList.empty()) { mActiveBehaviorList.sort(std::greater<ActiveBehavior>()); behavior_list.push_back(mActiveBehaviorList.front()); } } } }