Example #1
0
/** 以最快的方式跑到目标点
* Run to the destination point with the fastest method.
* \param agent the agent itself.
* \param act an atomic action caculated to go to pos for this cycle.
* \param pos the destination point.
* \param buffer point buffer, means the real destinantion is a cycle with the certer 
* 		of pos and radius of buffer.
* \param power the intend power to use.
* \param can_inverse true means can run in the inverse direction of the agent's body.
* \param turn_first true means that the agent should turn first to adjust the direction.
*/
void Dasher::GoToPoint(Agent & agent, AtomicAction & act, Vector target, double buffer, double power, bool can_inverse, bool turn_first)
{
	act.Clear();

	const Vector & my_pre_pos = agent.Self().GetPredictedPos(1);
	double dist = my_pre_pos.Dist(target);

	if (dist < buffer){
		act.mSucceed = true;
		return;
	}
	AngleDeg dirdiff = GetNormalizeAngleDeg((target - my_pre_pos).Dir() - agent.GetSelf().GetBodyDir());

	if (fabs(dirdiff) < 90.0){
		can_inverse = false; //不需要倒着跑
	}

	bool inverse = false;
	if (can_inverse){
		int cycle = CycleNeedToPointWithCertainPosture(agent.Self(), target, true);
		if (cycle < 9 && cycle < CycleNeedToPointWithCertainPosture(agent.Self(), target, false)){
			inverse = true;
		}
	}

	GoToPointWithCertainPosture(agent, act, target, buffer, power, inverse, turn_first);
}
DecisionData::DecisionData(Agent & agent):
	mAgent ( agent ),
	mWorldState ( agent.World() ),
	mBallState ( agent.World().Ball() ),
	mSelfState ( agent.Self() ),
	mInfoState ( agent.Info())
	{
}
BehaviorAttackData::BehaviorAttackData(Agent & agent):
	mAgent ( agent ),
    mWorldState ( agent.GetWorldState() ),
    mBallState ( agent.GetWorldState().GetBall() ),
	mSelfState ( agent.Self() ),
	mPositionInfo ( agent.Info().GetPositionInfo()),
	mInterceptInfo ( agent.Info().GetInterceptInfo()),
	mStrategy (agent.GetStrategy()),
    mFormation ( agent.GetFormation() )
{
	mFormation.Update(Formation::Offensive, "Offensive");
}
Example #4
0
/** 以确定的姿势(指倒着跑和正跑),跑到目标点
* Run to the destination point with a certain posture, forward or backword.
* \param agent the agent itself.
* \param act an atomic action caculated to go to pos for this cycle.
* \param pos the destination point.
* \param buffer point buffer, means the real destinantion is a cycle with the center
* 		of pos and radius of buffer.
* \param power the intend power to use.
* \param inverse true means run backward.
* \param turn_first true means that the agent should turn first to adjust the direction.
*/
void Dasher::GoToPointWithCertainPosture(Agent & agent, AtomicAction & act, Vector target, double buffer, double power, const bool inverse, bool turn_first)
{
	act.Clear();

	const Vector & my_pre_pos = agent.Self().GetPredictedPos(1);
	double dist = my_pre_pos.Dist(target);
	AngleDeg dirdiff = inverse? GetNormalizeAngleDeg((my_pre_pos - target).Dir() - agent.GetSelf().GetBodyDir()): GetNormalizeAngleDeg((target - my_pre_pos).Dir() - agent.GetSelf().GetBodyDir()); //需要转身的角度

	double bufang;

	buffer = Max(0.05, buffer); //TODO: wait test

	if (buffer > FLOAT_EPS){
		bufang = ASin(buffer / dist / 2) * 2;
		bufang = Max(10.0, bufang);
	}
	else {
		bufang = 0.0;
	}

	if (fabs(dirdiff) > bufang){
		TurnDashPlaning(agent, act, target, buffer, power, inverse, turn_first);
	}
	else {
		power = inverse? -fabs(power): fabs(power);
		power = agent.GetSelf().CorrectDashPowerForStamina(power);
		if (fabs(power) > FLOAT_EPS){
			act.mType = CT_Dash;
			act.mDashPower = AdjustPowerForDash(agent.Self(), target, buffer, power);
			act.mDashPower = agent.GetSelf().CorrectDashPowerForStamina(act.mDashPower);
			if (fabs(act.mDashPower) > FLOAT_EPS){
				act.mSucceed = true;
			}
			else {
				act.mType = CT_None; //power为零时就不要执行了,没意义
				TurnDashPlaning(agent, act, target, buffer, power, inverse, turn_first);//再次考虑转身,以免漏掉一线好的转身的机会
			}
		}
	}
}
Example #5
0
/**
* 考虑转身或直接dash
* Planing to turn or to dash.
* @param agent the agent itself.
* @param act an atomic action to return the caculated decision.
* @param target the target position to go to.
* @param buffer
* @param power the intend power for dash.
* @param inverse true means running backwards.
* @param turn_first true means turn first manually.
*/
void Dasher::TurnDashPlaning(Agent & agent, AtomicAction & act, Vector target, double buffer, double power, bool inverse, bool turn_first)
{
	act.Clear();

	power = inverse? -fabs(power): fabs(power);
	power = agent.GetSelf().CorrectDashPowerForStamina(power);

	PlayerState & self = agent.Self();
	const Vector & my_pre_pos = self.GetPredictedPos(1);
	double target_dist = my_pre_pos.Dist(target);
	AngleDeg target_ang = inverse? GetNormalizeAngleDeg((my_pre_pos - target).Dir() - agent.GetSelf().GetBodyDir()): GetNormalizeAngleDeg((target - my_pre_pos).Dir() - agent.GetSelf().GetBodyDir()); //需要转身的角度

	//DT_none
	//处理转身问题,可能1dash + 1turn更好
	double bufang;
	if(buffer > FLOAT_EPS){
		bufang = ASin(buffer / target_dist / 2) * 2;
		bufang = Max(10.0, bufang);
	}
	else{
		bufang = 0.0;
	}

	const double & effort = self.GetEffort();
	const double & accrate = self.GetDashPowerRate();
	const double & inertia_moment = self.GetInertiaMoment();
	const double & decay = self.GetPlayerDecay();
	const double & speedmax = self.GetEffectiveSpeedMax();
	const Vector & vel = self.GetVel();

	const double & facing = self.GetBodyDir();
	double speed = vel.Mod();


	double diffang = fabs(target_ang);
    double oneturnang = self.GetMaxTurnAngle();
	if(buffer < FLOAT_EPS && target_dist > 2.6){
		oneturnang += 2.6;
	}

	if(turn_first || diffang <= oneturnang || speed < 0.04){ //由于噪声的存在,在非身体方向也有速度,调也调不过来,太小时不如直接转,0.04是一般队员的误差极值
		act.mType = CT_Turn;
		act.mTurnAngle = target_ang;
		act.mSucceed = true;
		return;
	}
	else {
		//计算1 dash + 1turn;
		//下面都是算dash到什么速度最好
		double mspd1 = (180.0/ ( diffang + 10 ) - 1.0 ) / inertia_moment; //10是buf,不然容易调整后正好还转不过来
		double dash2spd = Min(mspd1 / decay, speedmax) / (1 + ServerParam::instance().playerRand());

		if( fabs(GetNormalizeAngleDeg(vel.Dir() - facing)) > 90.0){
			speed = -speed;
		}

		double spd_inf = Max(speed - accrate * ServerParam::instance().maxDashPower(), -dash2spd);
		double spd_sup = Min(speed + accrate * ServerParam::instance().maxDashPower(), dash2spd);
		Ray cur_r(self.GetPos(), facing);
		Vector pt_inf = cur_r.GetPoint(spd_inf * (1.0 + decay));
		Vector pt_sup = cur_r.GetPoint(spd_sup * (1.0 + decay));
		Vector pt;//要取得点
		bool bnegtive;//要跑的点是不是在身后
		Line pdl = Line(cur_r).GetPerpendicular(target);//垂线
		if(pdl.IsPointInSameSide(pt_inf, pt_sup)){
			if(fabs(GetNormalizeAngleDeg(facing-target_ang)) < 90.0){
				pt = pt_sup;
				bnegtive = (spd_sup<0);
			}
			else{
				pt = pt_inf;
				bnegtive = (spd_inf<0);
			}
		}
		else{
			double dist;
			bnegtive = !cur_r.Intersection(pdl, dist); //垂点
			pt = cur_r.GetPoint(dist);
		}
		double dis = pt.Dist(target);//两个周期后离point的距离,用来compare with 2 turn
		double twoturnang = oneturnang + 180.0 / (1.0 + inertia_moment * fabs(speed) * decay);
		if(twoturnang > diffang){
			const Vector & pt2 = self.GetPredictedPos(2);
			double dis2 = pt2.Dist(target);
			if(dis2 < dis || diffang > 102.6){ //一次转太大,误差也大不如直接2turn
				act.mType = CT_Turn;
				act.mTurnAngle = target_ang;
				act.mSucceed = true;
				return;
			}
		}
		double spd_need;
		if(bnegtive){
			spd_need = -(pt - self.GetPos()).Mod() / (1.0 + decay);
		}
		else{
			spd_need = (pt - self.GetPos()).Mod() / (1.0 + decay);
		}
		//会总是dash而dash后又转不过来...,看着就像不拿球
		double turnang_after_dash = 180.0 / (1.0 + inertia_moment * fabs(spd_need) * decay) - 5.0;
		if(GetAngleDegDiffer((target - pt).Dir(), facing) > turnang_after_dash ){
			act.mType = CT_Turn;
			act.mTurnAngle = target_ang;
			act.mSucceed = true;
			return;
		}
		double power = ( spd_need - speed ) / accrate / effort;

		power = MinMax(-ServerParam::instance().maxDashPower(), power, ServerParam::instance().maxDashPower());

		//I over
		act.mType = CT_Dash;
		act.mDashPower = AdjustPowerForDash(self, pt, FLOAT_EPS, power);
		act.mDashPower = agent.GetSelf().CorrectDashPowerForStamina(act.mDashPower);
		if(fabs(act.mDashPower) > FLOAT_EPS)
		{
			act.mSucceed = true;
		}
		else {
			act.mType = CT_Turn; //power为零时就不要执行了,没意义
			act.mTurnAngle = 0.0;
			act.mSucceed = true;
		}
	}
}