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

📄 dribble_between.c

📁 Brainstormers(头脑风暴)队是05年robocup冠军,这是05年Brainstormers公布的源代码,Brainstormers是robocup老牌的德国强队
💻 C
📖 第 1 页 / 共 2 页
字号:
/*Brainstormers 2D (Soccer Simulation League 2D)PUBLIC SOURCE CODE RELEASE 2005Copyright (C) 1998-2005 Neuroinformatics Group,                        University of Osnabrueck, GermanyThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.*//* * DribbleBetween skill * * @author Hannes Schulz <mail@hannes-schulz.de> * @version 0.9 * * vim:fdm=indent * */#include "dribble_between.h"#include "../policy/positioning.h"#include "ws_memory.h"#include "log_macros.h"#if 0 /* 1: debugging; 0: no debugging */#define POL(XXX)   LOG_POL(0,<<"DribbleBetween: "<<XXX)#define POL2(XXX)  LOG_POL(1,<<"DribbleBetween: "<<XXX)#define DRAW(XXX)  LOG_POL(0,<<_2D<<XXX)#define DRAW2(XXX) LOG_POL(1,<<_2D<<XXX)#else#define POL(XXX)   #define POL2(XXX) #define DRAW(XXX)  #define DRAW2(XXX) #endif#define KEEPQ2D(P1,P2,W1,W2) keep_players_in_quadrangle(P1,P2,W1,W2);#define MARK_POS(P,C) DRAW(C2D((P).x,(P).y,0.3,#C));#define MIN(X,Y) ((X<Y)?X:Y)#define MAX(X,Y) ((X>Y)?X:Y)#if 0#define DRIBBLE_STATS#endifDribbleBetween::DribbleBetween(){	dribbleAround = DribbleAround::getInstance();	lastDribbleTime = 0;	dribblingInsecure = false;}DribbleBetween* DribbleBetween::myInstance = NULL;DribbleBetween* DribbleBetween::getInstance() {	if(myInstance == NULL){		myInstance = new DribbleBetween();	}	return myInstance;}void DribbleBetween::setRelevantOpponents(){ // {{{1	static const float farAway = 5;	float myDistToDribbleTo = WSinfo::me->pos.distance(dribbleTo);	opps = WSinfo::valid_opponents;	int oppsInMyKickRange = 0;	switch(opps.num){		case 0: mode = DB_NO_OPP; return;		case 1: mode = DB_ONE_OPP; return;		default: break;	}	// find out how many players could roughly attack me in next cycle	// DribbleAround can only deal with one at a time.	float minDistDangerous = (3 * WSinfo::me->kick_radius);	for(int i=0;i<opps.num;i++){		if(opps[i]->pos.distance(WSinfo::ball->pos)<minDistDangerous)			oppsInMyKickRange++;	}	if(oppsInMyKickRange>1){		dribblingInsecure = true; // TODO: is this useful?		//mode = DB_TOO_MANY_OPP;		//return;	}		DRAW(C2D(dribbleTo.x,dribbleTo.y,0.2,"red"));	//Vector toFarAway = dribbleTo - WSinfo::me->pos;	Vector toFarAway;	toFarAway.init_polar(farAway,WSinfo::me->ang);	toFarAway.normalize(farAway);	//Vector justBehind = WSinfo::me->pos - dribbleTo;	Vector justBehind;	justBehind.init_polar(-2*WSinfo::me->kick_radius,WSinfo::me->ang);	justBehind.normalize(2*WSinfo::me->kick_radius);	opps.keep_players_in_quadrangle(WSinfo::me->pos+justBehind,WSinfo::me->pos+toFarAway,4,6);	DRAW(Quadrangle2d(WSinfo::me->pos+justBehind,WSinfo::me->pos+toFarAway,4,6));	for(int i=0;i<opps.num;i++){		DRAW(C2D(opps[i]->pos.x,opps[i]->pos.y,1.1*opps[i]->kick_radius,"blue"));	}	/*	 * TODO: use lotfusses to find out whether two opponents are on the same side of me	 * and remove the one further away.	 *	 for(int i = 0; i<maxNum;i++){		if(opps.num>=2){			Vector between;			between.x = (opps[0]->pos.x + opps[1]->pos.x)/2;			between.y = (opps[0]->pos.y + opps[1]->pos.y)/2;			if((    WSinfo::me->pos.y > opps[0]->pos.y						&& WSinfo::me->pos.y > opps[1]->pos.y)					|| (WSinfo::me->pos.y < opps[0]->pos.y						&& WSinfo::me->pos.y < opps[1]->pos.y)){				// both are on same side:				// remove the one further away				opps.remove(opps[1]);  			}			//else if(opps[0]->pos.distance(opps[1]->pos)<(WSinfo::me->pos.distance(between))){				// too close together				// remove the one further away				//opps.remove(opps[1]);  			//}		}else break;	}	*/	switch(opps.num){		case 0: mode = DB_NO_OPP;break;		case 1: mode = DB_ONE_OPP;break;		case 2: mode = DB_TWO_OPP;break;		default: mode = DB_TOO_MANY_OPP;	}} // }}}1float DribbleBetween::getValueForDribbleDir(float dribbleAngle){	static const float maxLookAhead = 9.;	static const float minLookAhead = -4;	Vector toDribbleTo = (dribbleTo-WSinfo::me->pos);	Vector notFurtherThan(toDribbleTo.ARG()+ANGLE(dribbleAngle));	Vector atLeastThatFar(toDribbleTo.ARG()+ANGLE(dribbleAngle));	notFurtherThan.normalize(maxLookAhead);	atLeastThatFar.normalize(minLookAhead);	notFurtherThan += WSinfo::me->pos;	atLeastThatFar += WSinfo::me->pos;	// GoStraightCheck BEGIN	// TODO: does this work? Is it good?  /*	WSpset opps = WSinfo::valid_opponents;	Vector lookAhead;	static const float lookAheadLength = 8;	lookAhead.init_polar(lookAheadLength,notFurtherThan.ARG());	opps.keep_players_in_quadrangle(WSinfo::me->pos,WSinfo::me->pos+lookAhead,8,8);	if(opps.num==0 && WSinfo::me->pos.x>-10)		return -200.+(WSinfo::me->pos.x>20?(WSinfo::me->pos+lookAhead).distance(HIS_GOAL_CENTER):0);    */	// GoStraightCheck END	opps = WSinfo::valid_opponents;	opps += WSinfo::valid_teammates_without_me;	WS::Player leftBorder, rightBorder;  	leftBorder.pos.init_polar(.5*maxLookAhead,toDribbleTo.ARG()+ANGLE(90));	leftBorder.pos += WSinfo::me->pos;	leftBorder.vel  = Vector(0,0);	leftBorder.number = -5;	leftBorder.team = HIS_TEAM;	rightBorder.pos.init_polar(.5*maxLookAhead,toDribbleTo.ARG()+ANGLE(-90));	rightBorder.pos += WSinfo::me->pos;	rightBorder.vel  = Vector(0,0);	rightBorder.number = -6;	rightBorder.team = HIS_TEAM;	opps.append(&leftBorder);	opps.append(&rightBorder);	Vector lot;	float oppDistToLot,value=1;	float opponentValue;	float intervalLength = maxLookAhead - minLookAhead;	Vector posPlusVel;	bool isBehindMe;	for(int i=0;i<opps.num;i++){		posPlusVel = opps[i]->pos + opps[i]->vel;		Geometry2d::projection_to_line(lot, posPlusVel, Line2d(WSinfo::me->pos,notFurtherThan-WSinfo::me->pos));		// lot must be in range [atLeastThatFar,notFurtherThan] from me, only ahead		if(notFurtherThan.distance(lot)>intervalLength) continue;		if(WSinfo::me->pos.distance(lot)>maxLookAhead) continue;		isBehindMe = notFurtherThan.distance(lot)>maxLookAhead;				opponentValue = ((opps[i]->team == HIS_TEAM) ? 1 : 0.2);		if(opps[i]->number == WSinfo::ws->his_goalie_number)			opponentValue = 0.1;		opponentValue *= (posPlusVel.distance(WSinfo::me->pos)<4)?2:1;		//opponentValue *= (isBehindMe?-.5:1);		oppDistToLot   =  posPlusVel.distance(lot);		oppDistToLot  -=  8;		oppDistToLot  *= -1;		oppDistToLot   =  MIN(8,oppDistToLot);		oppDistToLot   =  MAX(-0,oppDistToLot);		oppDistToLot  *=  opponentValue;				value += (oppDistToLot*oppDistToLot);	}	return value;}Vector DribbleBetween::getTargetPos(){	float bestAngle=0;	float value, bestValue=1E6;	static const float maxDribbleAngle = DEG2RAD(70);	static const int numCheckedAngles = 25;	static const float angleIncrease = maxDribbleAngle/numCheckedAngles;	Vector toDribbleTo = (dribbleTo-WSinfo::me->pos);	Vector notOff;	bool goingToCenterAllowed = WSinfo::me->pos.x>10||fabs(WSinfo::me->pos.y)<8;	bool behindGoal;	bool toCenter;	for(float dribbleAngle = 0; dribbleAngle<maxDribbleAngle;dribbleAngle+=angleIncrease){		notOff.init_polar(14,toDribbleTo.ARG()+ANGLE(dribbleAngle));		notOff+=WSinfo::me->pos;		behindGoal = fabs(notOff.y)<.8*ServerOptions::goal_width;		toCenter   = fabs(notOff.y) < fabs(WSinfo::me->pos.y) - 5;		if((fabs(notOff.y)>FIELD_BORDER_Y-2 || fabs(notOff.x)>FIELD_BORDER_X-2)				&& !behindGoal){			//POL2("getTargetPos: "<<RAD2DEG(dribbleAngle)<< "?:\t Leads out of field");		}		else if(!goingToCenterAllowed && toCenter){			//POL2("getTargetPos: "<<RAD2DEG(dribbleAngle)<< "?:\t Leads to center");		}else{			value = getValueForDribbleDir(dribbleAngle);			//POL2("getTargetPos: "<<RAD2DEG(dribbleAngle)<< "?:\t"<< value);			if(value<bestValue){				bestValue = value;				bestAngle = dribbleAngle;			}		}		notOff.init_polar(14,toDribbleTo.ARG()+ANGLE(-dribbleAngle));		notOff+=WSinfo::me->pos;		behindGoal = fabs(notOff.y)<.8*ServerOptions::goal_width;		toCenter   = fabs(notOff.y) < fabs(WSinfo::me->pos.y) - 5;		if((fabs(notOff.y)>FIELD_BORDER_Y-2 || fabs(notOff.x)>FIELD_BORDER_X-2)				&& !behindGoal){			//POL2("getTargetPos: "<<RAD2DEG(-dribbleAngle)<< "?:\t Leads out of field");		}else if(!goingToCenterAllowed && toCenter){			//POL2("getTargetPos: "<<RAD2DEG(-dribbleAngle)<< "?:\t Leads to center");		}else{			value = getValueForDribbleDir(-dribbleAngle);			//POL2("getTargetPos: "<<RAD2DEG(-dribbleAngle)<< "?:\t"<< value);			if(value<bestValue){				bestValue = value;				bestAngle = -dribbleAngle;			}		}		//if(bestValue < 2) break; // TODO: does this help?	}	POL("Dribble Dir has value "<<bestValue);	Vector dest;	dest.init_polar(20,toDribbleTo.ARG()+ANGLE(bestAngle));	dest+=WSinfo::me->pos;	DRAW(L2D(WSinfo::me->pos.x,WSinfo::me->pos.y,dest.x,dest.y,"green"));		if(dest.distance(WSinfo::me->pos)<2){		POL2("going for dribbleTo instead of dribbling between");		dest = dribbleTo;	}	if(fabs(WSinfo::me->pos.x)>FIELD_BORDER_X-4){		POL2("going for HIS_GOAL_CENTER instead of dribbling between");		dest = HIS_GOAL_CENTER;	}	bool amICloseToFieldBorder = 		(fabs(lastTarget.x)>FIELD_BORDER_X-2 ||		 fabs(lastTarget.y)>FIELD_BORDER_Y-2)		&&(		   fabs(WSinfo::me->pos.x) > FIELD_BORDER_X - 5		|| fabs(WSinfo::me->pos.y) > FIELD_BORDER_Y - 5);	bool isOldTargetInBadAngleButNewNot =		      fabs(Tools::my_angle_to(lastTarget).get_value_mPI_pPI())>DEG2RAD(80)			 && fabs(Tools::my_angle_to(dest)      .get_value_mPI_pPI())<DEG2RAD(80);	if(WSinfo::ws->time - lastDribbleTime > 3){		lastTarget = dest;		dribbleAroundTargetValue = bestValue;		dribbleAround->resetRequest();		targetTimeCounter = 0;	}else if((targetTimeCounter > 4 && mode!=DB_NO_OPP)			   ||targetTimeCounter >5){		lastTarget = dest;		dribbleAroundTargetValue = bestValue;		dribbleAround->resetRequest();		targetTimeCounter = 0;	}else if(WSinfo::me->pos.distance(lastTarget)<1){		lastTarget = dest;		dribbleAroundTargetValue = bestValue;		dribbleAround->resetRequest();		targetTimeCounter = 0;	}else if(amICloseToFieldBorder){		lastTarget = dest;		dribbleAroundTargetValue = bestValue;		dribbleAround->resetRequest();

⌨️ 快捷键说明

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