⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 visualsystem.cpp

📁 2002年
💻 CPP
字号:
#include "visualsystem.h"
#include "strategy.h"
#include "worldmodel.h"
#include "perceptron.h"
#include "skill.h"
#include "agent.h"
#include "log.h"

/***********************   Visual System   *****************************************/
VisualSystem::VisualSystem(){
}



void VisualSystem::Raise(VisualObjType otype, AngleDeg angle, float priority){
	if(Agent::mediator.ValidRequestAng(angle)){
		Agent::mediator.enroll(priority, angle);
		DoLog(LOG_VDEC, "A%.0f, P%.3f", angle, priority);
	}else{
		DoLog(LOG_VDEC, "Rejected A%.0f, P%.3f", angle, priority);
	}
}

void VisualSystem::Raise(VisualObjType otype, AngleDeg angle, AngleDeg distribute, float priority){
	if(distribute < 2.0f){
		Raise(otype, angle, priority);
	}else{
		Raise(otype, angle, 0.7f * priority);
		Raise(otype, angle - distribute, 0.4f * priority);
		Raise(otype, angle + distribute, 0.4f * priority);
	}
}

void VisualSystem::Raiseplayer(Player& p, float priority){
	if(!p.IsValidObject()){
		DoLog(LOG_VDEC, "invalid player%d, aborted", p.InsideNO); 
		return;
	}
	RingSector* rs = &p.domain.Data(situation.CurrentTime);
	if(p.domain.IsDataKnown(situation.CurrentTime) && rs->IsValid()){
		Raise(VO_player, rs->angles.Data(0).mean, rs->angles.Data(0).delta + ATan(1.0f/rs->radius.mean), priority);
		return;
	}

	float radius = p.ActiveRadius(situation.CurrentTime);
	float dist = Max(p.distance + 0.001f, radius);
	float spreadangle = ASin(radius / dist);
	if(p.Last_seen_time() != p.original_postime){//hearpos isn't accurate enough.
		spreadangle += 10.0f;
	}

	DoLog(LOG_VDEC, "find %d %.2f", p.InsideNO, priority);
	Findforgetobj(VO_player, p.global_angle, spreadangle, priority);
}

/******************/
void VisualSystem::Findforgetobj(VisualObjType otype, AngleDeg angle, AngleDeg distribute, float maxpriority){
	AngleDeg tangle = angle - distribute;
	float priority;
	int i;
	for(i = 0; i < 4; i++){
		float conf = FieldInfo.DirConf(tangle);
		if(conf < 0.9f && !Predictseen(tangle)){
			priority = Min(4.0f * (1 - conf), 1.0f);
			Raise(otype, tangle, maxpriority * priority * 0.5f);
		}
		tangle += distribute * 0.666f;
	}

	
}

void VisualSystem::GetActionInf(){
	Agent::mediator.Getbestaction(bestaction);
	nextselfpos = Self.pos + Self.global_vel;
	if(bestaction.GetCMDType() == CMD_dash){
		nextselfpos += Polar2Vector(bestaction.GetPower() * Skill::action.Dashrate(), Self.bodyfacing);
	}
	DoLog(LOG_VDEC,"next self pos(%.2f, %.2f)", nextselfpos.x, nextselfpos.y);
}


bool VisualSystem::Isballbyfeel(){
	if(!ball.pos_valid()) return false; 
	if(ball.distance > ServerParam::feel_distance + ServerParam::ball_speed_max) return false;

	if(ball.kickable())	return true;

	Vector ballgap = ball.posgap.ChkData(situation.CurrentTime) + ball.velgap.ChkData(situation.CurrentTime);
	if((ball.PredictPos(1) - nextselfpos).mod() < ServerParam::feel_distance - ballgap.mod())
		return true;
	else
		return false;
}

void VisualSystem::DoVisualDecision(){
	if(Vinfo_coming){
		DoLog(LOG_VDEC, "coming visual info (%.0f %.0f)" , NormalizeAngle(Vcominginfo_angle - Vcominginfo_width/2),
				NormalizeAngle(Vcominginfo_angle + Vcominginfo_width/2));	
	}

	GetActionInf();
	
	bool canfeelball = Isballbyfeel();
	DoViewModeDecision(canfeelball);

	Agent::mediator.SetViewRange();

	if(FindBall())	return;
//moved out
	if(!ClientParam::goalie){
		switch(bestaction.GetActionType()){
		case Action_pass:
		case Action_shoot:
		case Action_dribble:
		case Action_fastdribble:
		case Action_holdball:
		case Action_avoidenemy:
		case Action_clear://handleball
		case Action_passwait:
			break;
		case Action_interception://interception		
			break;
		case Action_positioning_offense:
		case Action_positioning_offside:
			break;
		case Action_positioning_defense:
			break;
		case Action_positioning_block:
		case Action_positioning_mark:
			break;
		case Action_none:
		default:		
			break;	
		}
	}else if(ClientParam::goalie){
	}

}
bool VisualSystem::FindBall(){
	if((Predictconf(ball.global_angle) < 0.8f || (!ball.Isforgot() && ball.pos_conf > 0.5f)) && !situation.ClockStopped){
		//just because haven't look at ball
		float distribute = ATan2(1.5f * (situation.CurrentTime - ball.original_postime), ball.distance);
		distribute = Max(distribute, 20.0f);
		Raise(VO_ball, ball.global_angle, 2 * distribute,1.0f);
	}else{
		DoSeek(1.0f, ball.global_angle);
	}
	return true;
}

/*****predict next visual inf within current view angle	*********/
/***** when clockstopped, prediction is invalid 		*********/
void VisualSystem::PredictNextSightInf(){	
	Vinfo_coming = bool(Self.NextViewCycle == situation.CurrentTime && !situation.ClockStopped);
	if(Vinfo_coming){
		Vcominginfo_angle = Self.headfacing;
		Vcominginfo_width = Self.MyViewWidth();
	}
}


float VisualSystem::GetPromisingAngle(VisualObjType obj, UNum idx){
	MobileObject* mobj = NULL;
	if(obj == VO_ball){
		mobj = & ball;
	}else if(obj == VO_player){
		mobj = &GetPlayer(idx);
	}
	if(mobj != NULL){
		if(mobj->pos_conf > ClientParam::min_valid_conf){
			//since have't be forgotten, why not look directly
			return mobj->global_angle; 
		}else{//
			//return DoSeek(mobj->global_angle, true);
		}
	}else{
		//shouldn't be here;
		//return DoSeek(mobj->global_angle, true);
	}
	return 0;
}
void VisualSystem::DoSeek(float maxpriority, AngleDeg recommendedangle){
	int seek_division = 12;
	int i;
	for(i = 0; i < seek_division; i++){
		float angle = recommendedangle + 360.0f/seek_division * i;
		float conf = Predictconf(angle);
		if(conf > 0.9f) continue;
		float priority = 0.3f + 0.3f * (1 - conf);
		priority += 0.8f * (float)fabs(i - seek_division/2)/seek_division*2; 
		Raise(VO_route, angle, priority * maxpriority);
	}
}


float VisualSystem::Predictconf(float ang){
	if(Predictseen(ang))
		return 1.0f;
	else
		return FieldInfo.DirConf(ang);
}

bool VisualSystem::Predictseen(float ang){
	if(Vinfo_coming && fabs(NormalizeAngle(ang - Vcominginfo_angle)) < Vcominginfo_width/2)
		return true;
	else
		return false;
}

/*****是否是新看过的队员,或即将看到他***********/
bool VisualSystem::Isobjconfmax(MobileObject& obj){
	if((situation.CurrentTime - obj.original_postime < 2 && obj.IsValidObject())
		|| (Predictseen(obj.global_angle) && !obj.Isforgot()))
		return true;
	else
		return false;
}

void VisualSystem::DoViewModeDecision(bool forcenarrow){
	if(Self.Is_goalie && situation.IsGoalieKick){
		Agent::mediator.SetViewWidth(VW_Wide);
		DoLog(LOG_SEE,"wide1");
		return;
	} 
	if(ball.distance > 50.0f){
		Agent::mediator.SetViewWidth(VW_Wide);
		DoLog(LOG_SEE,"wide2");
		return;
	}else if(ball.distance > 30.0f){
		Agent::mediator.SetViewWidth(VW_Normal);
		DoLog(LOG_SEE,"normal1");
		return;
	}

	if(forcenarrow){
		Agent::mediator.SetViewWidth(VW_Narrow);
		if(Self.NextViewCycle - situation.CurrentTime > 1){
			DoLog(LOG_SEE,"visualsystem1");
			sensory.change_view(VW_Narrow, VQ_High);
		}
		return;
	}
	if((ball.PredictPos(1) - nextselfpos).mod()  < ServerParam::feel_distance){
		Agent::mediator.SetViewWidth(VW_Narrow);
		DoLog(LOG_SEE,"visualsystem2");
		DoLog(LOG_VDEC, "make up for narrow mode");
		return;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -