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

📄 dribble_around.c

📁 Brainstormers(头脑风暴)队是05年robocup冠军,这是05年Brainstormers公布的源代码,Brainstormers是robocup老牌的德国强队
💻 C
📖 第 1 页 / 共 4 页
字号:
			  || (WSinfo::me->ang.get_value_mPI_pPI()>0 && WSinfo::me->pos.x<0)))		||(amICloseToFieldYBorder 			 && ((fabs(WSinfo::me->ang.get_value_mPI_pPI())>DEG2RAD(90) && WSinfo::me->pos.y<0)				|| (fabs(WSinfo::me->ang.get_value_mPI_pPI())<DEG2RAD(90) && WSinfo::me->pos.y>0)));	bool keepBallOnLeftSide = 		(!opp && isBallOnLeftSide) // no opponent and ball is on left side		|| (   opp                 // opponent ahead and ball left				&& oppOnMyLine				&& isBallOnLeftSide)		|| (   opp                 // opponent is on right side				&& !oppOnLeftSide				&& ( isBallOnLeftSide || ballChangeSidePossible))		|| (   opp                 // opponent is on left side				&& oppOnLeftSide				&& isBallOnLeftSide 				&& !ballChangeSidePossible)		|| isFieldBorderOnLeftSide;	bool haveToSwitchSides =		  ( isBallOnLeftSide && !keepBallOnLeftSide)		||(!isBallOnLeftSide && keepBallOnLeftSide);	haveToSwitchSides = haveToSwitchSides && ballChangeSidePossible;	bool switchSidesBehind = 		haveToSwitchSides && (				   (distToOpp<4                     // close to opp						&&  oppStraightAhead)           // who is directly ahead				|| (toBallFlAbs>DEG2RAD(90)         // ball behind me anyway					  && !(oppStraightBehind          // no opponent behind me							   && distToOpp<4))           // who is close		 );	Vector lot;	Geometry2d::projection_to_line(lot, WSinfo::ball->pos, Line2d(WSinfo::me->pos,Vector(WSinfo::me->ang)));	bool ballAhead = lot.distance(WSinfo::ball->pos)<1.1*ServerOptions::player_size;	bool ballPosOKForAdvancing = 		   !haveToSwitchSides		&& !ballAhead		&& toBallFlAbs<DEG2RAD(135)  // not too straight behind		// && WSinfo::me->pos.distance(WSinfo::ball->pos)>0.5 // TODO: is this necessary?		// avoid kicking when ball is far to left/right		&& (WSinfo::ball->pos.distance(WSinfo::me->pos) < (0.9*WSinfo::me->kick_radius)				|| toBallFlAbs<DEG2RAD(75)				|| toBallFlAbs>DEG2RAD(105));	bool closestOppDirectlyBehindMe = 		opp 		&& fabs(Tools::my_angle_to(opp->pos).get_value_mPI_pPI())>DEG2RAD(100)		&& !nextOppToMe.reachesPos;	bool breakThruOffsideLine = 		  WSinfo::his_team_pos_of_offside_line() - WSinfo::me->pos.x < 1.5		&& dribbleTo.x > WSinfo::his_team_pos_of_offside_line();	bool closestOppInMeWrongDir = 		opp		&& fabs((opp->ang - WSinfo::me->ang).get_value_mPI_pPI())>DEG2RAD(70)		&& opp->pos.distance(WSinfo::me->pos) < 1.5*WSinfo::me->kick_radius;	bool ignoreClosestOpp = 		  closestOppDirectlyBehindMe		||closestOppInMeWrongDir		||breakThruOffsideLine;	bool dontAdvanceChased = 		opp 		&& fabs(Tools::my_angle_to(opp->pos).get_value_mPI_pPI())>DEG2RAD(100)		&& opp->pos.distance(WSinfo::me->pos)<1.4*WSinfo::me->kick_radius		&& fabs((opp->vel.ARG()-WSinfo::me->ang).get_value_mPI_pPI())<DEG2RAD(30)		&& opp->vel.norm() > 0.4*opp->speed_max		&& (opp->vel.norm()>WSinfo::me->vel.norm());	POL2("getKickAhead: Chase! Do not advance.");	ANGLE deviate(keepBallOnLeftSide?DEG2RAD(10):DEG2RAD(-10));	if(ballPosOKForAdvancing && !dontAdvanceChased){		if(getKickAheadBallOK(cmd,ANGLE(0),ignoreClosestOpp)) 			return true;		else if(getKickAheadPrepareBall(cmd,keepBallOnLeftSide,true))			return true;	}	if(ballAhead && !dontAdvanceChased){		if(getKickAheadBallOK(cmd,deviate,ignoreClosestOpp)){		  POL("getKickAhead: BallPos not OK, deviating from 0?");			return true;		}	}	if(getKickAheadPrepareBall(cmd,keepBallOnLeftSide,switchSidesBehind))		return true;	Vector safestPos, bestPos;	getTargetsInMe(safestPos, bestPos);	bool chased = (Tools::my_angle_to(bestPos).get_value_mPI_pPI() < PI/7                  // best dest ahead			&& nextOppToMe.pos.distance(bestPos)<0.4			&& fabs(Tools::my_angle_to(WSinfo::ball->pos).get_value_mPI_pPI())<PI/3); // ball ahead of me	if(chased){		if(getKickAheadBallOK(cmd,deviate,true)){		  POL("getKickAhead: chased, deviating from 0?, ignoring closest opp");			return true;		}	}		if(getCmdKickToDest(cmd,bestPos,true,false)){		POL("getKickAhead: Kicking to best Pos in Dir.");		lastActionTaken = DA_KICK_AHEAD;		MARK_POS(bestPos, blue);		return true;	};	if(getCmdKickToDest(cmd,safestPos,true,false)){		POL("getKickAhead: Kicking to safest Pos.");		lastActionTaken = DA_KICK_AHEAD;		MARK_POS(safestPos, blue);		return true;	};	return false;}// getKickAheadBallOK {{{2bool DribbleAround::getKickAheadBallOK(Cmd& cmd, ANGLE deviate, bool ignoreClosestOpp){	POL2("In getKickAheadBallOK(), ignoreClosestOpp="<<ignoreClosestOpp);	ANGLE kick_angle = WSinfo::me->ang + deviate;	Cmd tmpCmd;	Vector new_my_pos,new_my_vel,new_ball_pos,new_ball_vel;	Vector old_new_my_pos,old_new_my_vel;	ANGLE new_my_ang;	bool goingInXDir = dribbleTo.x > WSinfo::me->pos.x + 5;	bool haventLookedThere = 		WSmemory::last_seen_in_dir(Tools::my_angle_to(dribbleTo))>3;	const int maxLookAhead = (!goingInXDir || opp&&opp->age>1)?1:8;	Vector afterNdash[maxLookAhead+1];	// kicking == doing nothing	basic_cmd->set_dash(0);	basic_cmd->get_cmd(tmpCmd);	Tools::model_cmd_main(WSinfo::me->pos,WSinfo::me->vel,WSinfo::me->ang,WSinfo::ball->pos,WSinfo::ball->vel,tmpCmd.cmd_main,new_my_pos,new_my_vel,new_my_ang,new_ball_pos,new_ball_vel,false);	old_new_my_pos = new_my_pos;	old_new_my_vel = new_my_vel;		// simulate 1st dash	basic_cmd->set_dash(maxSpeed);	basic_cmd->get_cmd(tmpCmd);	// before doing anything else, calculate how far we can get by	// maxLookAhead or less dashes	for(int i = 1 ; i<=maxLookAhead; i++){ // smaller bc we already did one!		Tools::model_cmd_main(old_new_my_pos,old_new_my_vel,WSinfo::me->ang,WSinfo::ball->pos,WSinfo::ball->vel,tmpCmd.cmd_main,new_my_pos,new_my_vel,new_my_ang,new_ball_pos,new_ball_vel,false);		old_new_my_pos = new_my_pos;		old_new_my_vel = new_my_vel;		afterNdash[i] = new_my_pos;	}		Vector lot,tmp,dest;	bool foundSafePos = false;	static const double maxDistToBall = 0.7*WSinfo::me->kick_radius;	WSpset pset;	Vector lotOnMyDirDiff;	Vector lotOnMyDir;	int nThDash;	bool ballLeavesKickRadius;	for(nThDash=maxLookAhead;nThDash>0; nThDash--){		if(nThDash*70 + 1300 > WSinfo::me->stamina) 			continue;		for(double furthest=0.8*WSinfo::me->kick_radius;furthest>0; furthest-=.1){			lotOnMyDirDiff.init_polar(furthest,WSinfo::me->ang);			lotOnMyDir = afterNdash[nThDash] + lotOnMyDirDiff; // right to me in 2 cycles			Geometry2d::projection_to_line(lot, lotOnMyDir, Line2d(WSinfo::ball->pos,Vector(kick_angle)));			if(nThDash<7 && !(fabs(WSinfo::me->pos.y)>FIELD_BORDER_Y-2))				lot = lot;			else				lot = lotOnMyDir + 0.5*(lot - lotOnMyDir);			// we know now the kick dir, figure out destination of kickCmd:			bool tooFar;			dest = getKickDestForBallPosInNCycles(lot,1+nThDash,tooFar);						if(tooFar) continue;			if(afterNdash[nThDash].distance(lot)<maxDistToBall){				foundSafePos = true;				break;			}		}		if(!foundSafePos)			continue;		pset = WSinfo::valid_opponents;		if(ignoreClosestOpp && opp)			pset.remove(opp);		pset.keep_and_sort_closest_players_to_point(4,lot);		if(fabs(lot.y)>FIELD_BORDER_Y-1 || fabs(lot.x)>FIELD_BORDER_X-3){			// Can catch ball outside field -- dont do this			foundSafePos = false;			continue;		}		// now calculate whether the ball will leave my kick_radius		// in the course of kick+dashes		new_ball_pos = dest;		new_ball_vel = dest - WSinfo::ball->pos;		ballLeavesKickRadius = false;		for(int i=1;i<=nThDash; i++){			new_ball_vel = ServerOptions::ball_decay*new_ball_vel;			new_ball_pos = new_ball_pos + new_ball_vel;			if(afterNdash[i].distance(new_ball_pos)>0.8*WSinfo::me->kick_radius){				ballLeavesKickRadius = true;				break;			}		}		// advance fast even if havent looked there if ball stays controlled		if(ballLeavesKickRadius && haventLookedThere){			foundSafePos = false;			continue;		}		bool betterInterceptorFound=false;		Vector his_lot;		float deltaPos;		Geometry2d::projection_to_line(his_lot, WSinfo::me->vel, Line2d(Vector(0,0),Vector(lot - WSinfo::me->pos)));		float myDeltaPos = WSinfo::me->pos.distance(his_lot);		for(int i=0;i<pset.num&&ballLeavesKickRadius;i++){			Geometry2d::projection_to_line(his_lot, pset[i]->vel, Line2d(Vector(0,0),Vector(lot - pset[i]->pos)));			deltaPos = pset[i]->pos.distance(his_lot);			if(pset[i]->pos.distance(lot)-WSinfo::me->pos.distance(lot)<0.5+0.15*nThDash + deltaPos-myDeltaPos){				// I loose control of the ball and my next opponent is closer to ball than I am				betterInterceptorFound=true;				break;			}		}		if(betterInterceptorFound){			foundSafePos=false;			continue;		}		break;	}	if(!foundSafePos){		POL2("getKickAheadBallOK: Advancing too risky, stopping it");		return false;	}	bool isBallOnLeftSide = (Tools::my_angle_to(WSinfo::ball->pos).get_value_mPI_pPI()>0);	Vector fallBack;	fallBack.init_polar(0.6,WSinfo::me->ang + (isBallOnLeftSide ? ANGLE(DEG2RAD(112)):ANGLE(DEG2RAD(-112))));	Vector inMyDir;	inMyDir.init_polar(0.3,WSinfo::me->ang);	bool canDash = true;	bool mustKick = false;	if(opp 			&& nextOppToMe.pos.distance(dest)<nextOppToMe.kick_radius+ServerOptions::ball_size){		POL2("getKickAheadBallOK: Do not advance in Opponent, moving ball to back!");		dest = fallBack + nextMeNA.pos;		canDash = false;		mustKick = true;	}	if(opp 			&& nextOppToMe.pos.distance(dest)<nextOppToMe.kick_radius+ServerOptions::ball_size){		POL2("getKickAheadBallOK: Do not advance in Opponent(2), moving ball to back!");		dest = fallBack + inMyDir + nextMeNA.pos;		canDash = false;		mustKick = true;	}	/*	 * Do NOT do this: upper level will request dash!	if(opp 			&& nextOppToMe.pos.distance(dest)<nextOppToMe.kick_radius+ServerOptions::ball_size){		POL2("getKickAheadBallOK: Do not advance in Opponent(3), last chance");		Vector safestPos, bestPos;		getTargetsInMe(safestPos, bestPos);		if(getCmdKickToDest(cmd,bestPos,true,false)){			POL("Kicking ball to best position");			MARK_POS(safestPos, blue);			return true;		}		if(getCmdKickToDest(cmd,safestPos,true,false)){			POL("Kicking ball to safest position");			MARK_POS(safestPos, blue);			return true;		}	}	*/	POL2("getKickAheadBallOK: Should get ball after "<<nThDash<< " dashes after kick");	MARK_POS(lotOnMyDir, green);	MARK_POS(lot, green);	DRAW(L2D(WSinfo::ball->pos.x,WSinfo::ball->pos.y,lot.x,lot.y,"green"));	DRAW(C2D(afterNdash[nThDash].x,afterNdash[nThDash].y,WSinfo::me->kick_radius,"green"));	if(getCmdKickToDest(cmd,dest,false,false)){		POL("getKickAheadBallOK: Ball moving in right direction, kicking ahead.");		if(canDash)			setRequest(DAREQ_DASH);		else if(mustKick)			setRequest(DAREQ_KICK);		lastActionTaken = DA_KICK_AHEAD;		MARK_POS(dest, blue);		return true;	};	return false;}// getKickAheadPrepareBall {{{2bool DribbleAround::getKickAheadPrepareBall(Cmd& cmd, bool keepBallOnLeftSide, bool switchSidesBehind){	POL2("In getKickAheadPrepareBall()");	ANGLE toBall = Tools::my_angle_to(WSinfo::ball->pos);	double toBallFl = toBall.get_value_mPI_pPI();	double toBallFlAbs = fabs(toBallFl);	bool isBallOnLeftSide = (toBallFl>0);	bool haveToSwitchSides =		  ( isBallOnLeftSide && !keepBallOnLeftSide)		||(!isBallOnLeftSide && keepBallOnLeftSide);	if(!haveToSwitchSides){		Vector dest, dest1, dest2;		Vector inMyDir;		inMyDir.init_polar(0.4,WSinfo::me->ang);		dest1.init_polar(0.8,WSinfo::me->ang + (isBallOnLeftSide ? ANGLE(5*PI/8):ANGLE(-5*PI/8)));		dest1+= nextMeNA.pos;		dest2 = dest1 + inMyDir;		dest = ((WSinfo::ball->pos.sqr_distance(dest1)<WSinfo::ball->pos.sqr_distance(dest2))?dest1:dest2);		if(getCmdKickToDest(cmd,dest,true,false)){			POL("getKickAheadPrepareBall: Preparing ball on same side.");			setRequest(DAREQ_KICK);			MARK_POS(dest, blue);			return true;		}	}		// now the switch sides case	// TODO: this is always true!?	bool ballChangeSidePossible = true ||		(WSinfo::ball->pos.distance(WSinfo::me->pos)>.4)		&& (				  (toBallFlAbs<DEG2RAD(50))				||(toBallFlAbs>DEG2RAD(130)));		if(!ballChangeSidePossible){		bool toMyLine = (switchSidesBehind && toBallFlAbs>DEG2RAD(90))			||(!switchSidesBehind && toBallFlAbs<DEG2RAD(90));		Vector dest;		if(toMyLine){			dest.init_polar((switchSidesBehind?-0.8:0.8)*WSinfo::me->kick_radius,WSinfo::me->ang);			dest+=nextMeNA.pos;			if(getCmdKickToDest(cmd,dest,true,false)){				POL("getKickAheadPrepareBall: Cannot change sides, preparing by kicking on my line.");				setRequest(DAREQ_KICK);				MARK_POS(dest, blue);				return true;			}		}		ANGLE toDest;		if(isBallOnLeftSide)			toDest = ANGLE(WSinfo::me->ang + ANGLE(switchSidesBehind?-5*PI/8:-3*PI/8));		else			toDest = ANGLE(WSinfo::me->ang + ANGLE(switchSidesBehind? 5*PI/8: 3*PI/8));		dest.init_polar(0.6*WSinfo::me->kick_radius, toDest);		dest+=nextMeNA.pos;		if(getCmdKickToDest(cmd,dest,true,false)){			POL("getKickAheadPrepareBall: Cannot change sides, preparing by kicking in desired dir.");			setRequest(DAREQ_KICK);			MARK_POS(dest, blue);			return true;		}	}	// we have to change sides and ball change sides is possible	Vector dest;	ANGLE toDest;	if(keepBallOnLeftSide)		toDest = ANGLE(WSinfo::me->ang + ANGLE(switchSidesBehind? 5*PI/8: 3*PI/8));	else		toDest = ANGLE(WSinfo::me->ang + ANGLE(switchSidesBehind?-5*PI/8:-3*PI/8));	dest.init_polar(0.6*WSinfo::me->kick_radius,toDest);	dest += nextMeNA.pos;	if(getCmdKickToDest(cmd,dest,true,false)){		POL("getKickAheadPrepareBall: Can change sides, doing so.");		setRequest(DAREQ_KICK);		MARK_POS(dest, blue);		return true;	}	return false;}// getKickForTurn {{{2bool DribbleAround::getKickForTurn(Cmd& cmd){	ANGLE toBall       =     (dribbleTo-WSinfo::me->pos).ANGLE_to(WSinfo::ball->pos - WSinfo::me->pos);	ANGLE toOpp        = opp?(dribbleTo-WSinfo::me->pos).ANGLE_to(opp->pos          - WSinfo::me->pos):ANGLE(0);	float toOppFl      = toOpp.get_value_mPI_pPI();	float toBallFl     = toBall.get_value_mPI_pPI();	ANGLE aToDribbleTo = (dribbleTo - WSinfo::me->pos).ARG();	bool isBallOnLeftSide = toBallFl > 0;	bool isOppLeft        = toOppFl  > 0;	POL2("getKickForTurn: Opp will be left="<<isOppLeft << " toOpp="<<RAD2DEG(toOppFl));	POL2("getKickForTurn: Ball is be left="<<isBallOnLeftSide << " toBall="<<RAD2DEG(toBallFl));	float toDestFl = Tools::my_angle_to(dribbleTo).get_value_mPI_pPI();	bool turnALot  = fabs(toDestFl) > DEG2RAD(80);	Cmd tmpCmd;	Vector new_my_pos,new_my_vel,new_ball_pos,new_ball_vel;	Vector old_new_my_pos,old_new_my_vel;	ANGLE new_my_ang, old_new_my_ang;	// simulate kick	basic_cmd->set_dash(0);	basic_cmd->get_cmd(tmpCmd);	Tools::model_cmd_main(WSinfo::me->pos,WSinfo::me->vel,WSinfo::me->ang,WSinfo::ball->pos,WSinfo::ball->vel,tmpCmd.cmd_main,new_my_pos,new_my_vel,new_my_ang,new_ball_pos,new_ball_vel,false);	old_new_my_pos = new_my_pos;	old_new_my_vel = new_my_vel;

⌨️ 快捷键说明

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