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());
			}
		}

	}
}