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

📄 player.c

📁 机器足球2D比赛程序 对trlen_base_2002的改进
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (WM->isBeforeKickOff()) {		if (formations->getFormation() != FT_INITIAL ||	// not in kick_off formation				posAgent.getDistanceTo(WM->getStrategicPosition()) > 2.0) {			formations->setFormation(FT_INITIAL);	// go to kick_off formation			ACT->				putCommandInQueue(teleportToPos						(WM->getStrategicPosition()));		} else			// else turn to center		{			ACT->putCommandInQueue(turnBodyToPoint(VecPosition(0, 0), 0));			ACT->putCommandInQueue(alignNeckWithBody());		}		return;	}	if (WM->getConfidence(OBJECT_BALL) < PS->getBallConfThr()) {	// confidence ball too  low		ACT->putCommandInQueue(searchBall());	// search ball		ACT->putCommandInQueue(alignNeckWithBody());	} else if (WM->getPlayMode() == PM_PLAY_ON || WM->isFreeKickThem() ||			WM->isCornerKickThem()) {		if (WM->isBallCatchable()) {			ACT->putCommandInQueue(soc = catchBall());			ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));		} else if (WM->isBallKickable()) {			soc = kickTo(VecPosition(0, posAgent.getY() * 2.0), 2.0);			ACT->putCommandInQueue(soc);			ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));		} else if (WM->				isInOwnPenaltyArea(getInterceptionPointBall(&i, true))				&& WM->getFastestInSetTo(OBJECT_SET_PLAYERS,					OBJECT_BALL,					&i) ==				WM->getAgentObjectType()) {			ACT->putCommandInQueue(soc = intercept(true));			ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));		} else {			// make line between own goal and the ball			VecPosition posMyGoal = (WM->getSide() == SIDE_LEFT)				? SoccerTypes::getGlobalPositionFlag(OBJECT_GOAL_L,						SIDE_LEFT)				: SoccerTypes::getGlobalPositionFlag(OBJECT_GOAL_R,						SIDE_RIGHT);			Line lineBall =				Line::makeLineFromTwoPoints(WM->getBallPos(), posMyGoal);			// determine where your front line intersects with the line from ball			VecPosition posIntersect = lineFront.getIntersection(lineBall);			// outside rectangle, use line at side to get intersection			if (posIntersect.isRightOf(posRightTop))				posIntersect = lineRight.getIntersection(lineBall);			else if (posIntersect.isLeftOf(posLeftTop))				posIntersect = lineLeft.getIntersection(lineBall);			if (posIntersect.getX() < -49.0)				posIntersect.setX(-49.0);			// and move to this position			if (posIntersect.getDistanceTo(WM->getAgentGlobalPosition()) >					0.5) {				soc =					moveToPos(posIntersect,							PS->getPlayerWhenToTurnAngle());				ACT->putCommandInQueue(soc);				ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));			} else {				ACT->putCommandInQueue(soc =						turnBodyToObject(OBJECT_BALL));				ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));			}		}	} else if (WM->isFreeKickUs() == true || WM->isGoalKickUs() == true) {		if (WM->isBallKickable()) {			if (WM->getTimeSinceLastCatch() == 25 && WM->isFreeKickUs()) {				// move to position with lesser opponents.				if (WM->getNrInSetInCircle(OBJECT_SET_OPPONENTS,							Circle(posRightTop, 15.0)) <						WM->getNrInSetInCircle(OBJECT_SET_OPPONENTS,							Circle(posLeftTop, 15.0)))					soc.makeCommand(CMD_MOVE, posRightTop.getX(),							posRightTop.getY(), 0.0);				else					soc.makeCommand(CMD_MOVE, posLeftTop.getX(),							posLeftTop.getY(), 0.0);				ACT->putCommandInQueue(soc);			} else if (WM->getTimeSinceLastCatch() > 28) {				soc = kickTo(VecPosition(0, posAgent.getY() * 2.0), 2.0);				ACT->putCommandInQueue(soc);			} else if (WM->getTimeSinceLastCatch() < 25) {				VecPosition posSide(0.0, posAgent.getY());				if (fabs((posSide - posAgent).getDirection() - angBody) >						10) {					soc = turnBodyToPoint(posSide);					ACT->putCommandInQueue(soc);				}				ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));			}		} else if (WM->isGoalKickUs()) {			ACT->putCommandInQueue(soc = intercept(true));			ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));		} else			ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));	} else {		ACT->putCommandInQueue(soc = turnBodyToObject(OBJECT_BALL));		ACT->putCommandInQueue(turnNeckToObject(OBJECT_BALL, soc));	}}/*!This method determines whether a player should say something.   \return bool indicating whether the agent should say a message */bool Player::shallISaySomething(){	bool bReturn;	bReturn =		((WM->getCurrentTime() - m_timeLastSay) >= SS->getHearDecay());	bReturn &= amIAgentToSaySomething();	bReturn &= (WM->getCurrentCycle() > 0);	return bReturn;}/*! This method returns a boolean indicating whether I should communicate my  world model to the other agents.   \return boolean indicating whether I should communicate my world model. */bool Player::amIAgentToSaySomething(){	// if got good information of the ball, communicate. 	if (WM->getTimeChangeInformation(OBJECT_BALL) == WM->getCurrentTime()			|| WM->getRelativeDistance(OBJECT_BALL) < SS->getVisibleDistance())		return true;	return false;}/*! This method is used to communicate the status of the ball, that is its  position and velocity.*/SoccerCommand Player::sayBallStatus(){	char strMsg[MAX_SAY_MSG];	// First add al values to a positive interval, since then we don't need	// another byte for the minus sign. then take one digit at a time	VecPosition posBall = WM->getGlobalPosition(OBJECT_BALL);	VecPosition velBall = WM->getGlobalVelocity(OBJECT_BALL);	double x = min(posBall.getX() + 52.5, 99.9);	sprintf(strMsg, "%c%c%c%c%c%c%c%c",			'0' + ((int) (x) % 100) / 10,			'0' + ((int) (x) % 100) % 10,			'0' + ((int) (posBall.getY() + 34.0) % 100) / 10,			'0' + ((int) (posBall.getY() + 34.0) % 100) % 10,			'0' + ((int) ((velBall.getX() + 2.7) * 10)) / 10,			'0' + ((int) ((velBall.getX() + 2.7) * 10)) % 10,			'0' + ((int) ((velBall.getY() + 2.7) * 10)) / 10,			'0' + ((int) ((velBall.getY() + 2.7) * 10)) % 10);	return communicate(strMsg);}/*!This method does nothing except updating the worldmodel after each arrival of  a see or sense_body message. Using this test program it is possible to  control the commands of the agent using the standard input and see the  resulting behavior of the agent. */void Player::test_only_update(){	while (bContLoop) {		WM->updateAll();		if (WM->waitForNewInformation() == false) {			printf("Server dead; exiting");			bContLoop = false;		}	}}/*!This method can be called in a separate thread (see pthread_create) since  it returns a void pointer. It is assumed that this function receives a  BasicPlayer class as argument. The only thing this function does  is starting the method handleStdin() from the corresponding BasicPlayer  class that listens to user input from the keyboard. This function is  necessary since a method from a class cannot be an argument of  pthread_create.  \param v void pointer to a BasicPlayer class.  \return should never return since function handleStdin has infinite loop*/void *stdin_callback(void *v){	Log.log(1, "Starting to listen for user input");	Player *p = (Player *) v;	p->handleStdin();	return NULL;}/*!This method listens for input from the keyboard and when it receives this  input it converts this input to the associated action. See  showStringCommands for the possible options. This method is used together  with the SenseHandler class that sends an alarm to indicate that a new  command can be sent. This conflicts with the method in this method that  listens for the user input (fgets) on Linux systems (on Solaris this isn't a  problem). The only known method is to use the flag SA_RESTART with this  alarm function, but that does not seem to work under Linux. If each time  the alarm is sent, this gets function unblocks, it will cause major  performance problems. This function should not be called when a whole match  is played! */void Player::handleStdin(){	char buf[MAX_MSG];	while (bContLoop) {		fgets(buf, MAX_MSG, stdin);	// does unblock with signal !!!!!		printf("after fgets: %s\n", buf);		executeStringCommand(buf);	}}/*!This method prints the possible commands that can be entered by the user.  The whole name can be entered to perform the corresponding command, but  normally only the first character is sufficient. This is indicated by  putting brackets around the part of the command that is not needed.  \param out output stream to which the possible commands are printed */void Player::showStringCommands(ostream & out){	out << "Basic commands:" << endl <<		" a(ctions)" << endl <<		" c(atch) direction" << endl <<		" cs(lientsettings" << endl <<		" d(ash) power [ times ]" << endl <<		" de(bug) nr_cycles" << endl <<		" g(oto) x y" << endl <<		" h(elp)" << endl <<		" i(ntercept) x y" << endl <<		" k(ick) power angle" << endl <<		" ka x y endspeed " << endl <<		" m(ove) x y" << endl <<		" n(eck) angle" << endl <<		" o(pponents in cone) width dist" << endl <<		" p(redict cycles to) x y" << endl <<		" q(uit)" << endl <<		" s(ay) message" << endl <<		" ss(erversettings)" << endl <<		" t(urn) angle" << endl <<		" v(iewmode) narrow | normal | wide low | high" << endl <<		" w(orldmodel)" << endl;}/*!This method executes the command that is entered by the user. For the  possible command look at the method showStringCommands.  \param str string that is entered by the user  \return true when command could be executed, false otherwise */bool Player::executeStringCommand(char *str){	SoccerCommand socCommand;	int i;	double x, y;	switch (str[0]) {		case 'a':			// actions			WM->showQueuedCommands();			break;		case 'c':			// catch dir or cs			if (strlen(str) > 1 && str[1] == 's') {				PS->show(cout, ":");				break;			}			socCommand.makeCommand(CMD_CATCH, Parse::parseFirstInt(&str));			break;		case 'd':			// dash			socCommand.commandType = CMD_DASH;			socCommand.dPower = Parse::parseFirstDouble(&str);			socCommand.iTimes = Parse::parseFirstInt(&str);			if (socCommand.iTimes == 0)				socCommand.iTimes = 1;			break;		case 'h':			// help			showStringCommands(cout);			return true;		case 'k':			// kick or ka (kick advanced)			socCommand.commandType = CMD_KICK;			if (str[1] == 'a')	// advanced kick			{				double x = Parse::parseFirstDouble(&str);				double y = Parse::parseFirstDouble(&str);				double e = Parse::parseFirstDouble(&str);				socCommand = kickTo(VecPosition(x, y), e);			} else {				socCommand.dPower = Parse::parseFirstDouble(&str);				socCommand.dAngle = Parse::parseFirstDouble(&str);			}			break;		case 'm':			// move			socCommand.commandType = CMD_MOVE;			socCommand.dX = Parse::parseFirstDouble(&str);			socCommand.dY = Parse::parseFirstDouble(&str);			socCommand.dAngle = Parse::parseFirstDouble(&str);			break;		case 'n':			// turn_neck			socCommand.commandType = CMD_TURNNECK;			socCommand.dAngle = Parse::parseFirstDouble(&str);			break;		case 'o':			// count nr opp in cone			x = Parse::parseFirstDouble(&str);			y = Parse::parseFirstDouble(&str);			i = WM->getNrInSetInCone(OBJECT_SET_OPPONENTS, x,					WM->getAgentGlobalPosition(),					WM->getAgentGlobalPosition() +					VecPosition(y,						WM->getAgentGlobalNeckAngle(),						POLAR));			printf("%d opponents\n", i);			return true;		case 'p':			// predict cycles to point			x = Parse::parseFirstDouble(&str);			y = Parse::parseFirstDouble(&str);			i = WM->predictNrCyclesToPoint(WM->getAgentObjectType(),					VecPosition(x, y),					PS->getPlayerWhenToTurnAngle());			printf("%d cycles\n", i);			return true;		case 'q':			// quit			bContLoop = false;			return true;		case 's':			// ss (serversettings) or say			if (strlen(str) > 1 && str[1] == 's') {				SS->show(cout, ":");				break;			}			socCommand.commandType = CMD_SAY;			Parse::gotoFirstOccurenceOf(' ', &str);			Parse::gotoFirstNonSpace(&str);			strcpy(socCommand.str, str);			break;		case 't':			// turn			socCommand.commandType = CMD_TURN;			socCommand.dAngle = Parse::parseFirstDouble(&str);			break;		case 'v':			// change_view			socCommand.commandType = CMD_CHANGEVIEW;			Parse::gotoFirstOccurenceOf(' ', &str);			Parse::gotoFirstNonSpace(&str);			socCommand.va = SoccerTypes::getViewAngleFromStr(str);			Parse::gotoFirstOccurenceOf(' ', &str);			Parse::gotoFirstNonSpace(&str);			socCommand.vq = SoccerTypes::getViewQualityFromStr(str);			break;		case 'w':			// worldmodel			WM->show();			return true;		default:			// default: send entered string			ACT->sendMessage(str);			return true;	}	if (socCommand.commandType != CMD_ILLEGAL)	// when socCommand is set		ACT->putCommandInQueue(socCommand);	// send it.	return true;}/*! This method is called when a penalty kick has to be taken (for both the   goalkeeper as the player who has to take the penalty. */void Player::performPenalty(){	VecPosition pos;	int iSide = (WM->getSide() == WM->getSidePenalty())? -1 : 1;	VecPosition posPenalty(iSide * (52.5 - SS->getPenDistX()), 0.0);	VecPosition posAgent = WM->getAgentGlobalPosition();	AngDeg angBody = WM->getAgentGlobalBodyAngle();	SoccerCommand soc(CMD_ILLEGAL);	static PlayModeT pmPrev = PM_ILLEGAL;	// raise number of penalties by one when a penalty is taken	if ((WM->getSide() == SIDE_LEFT &&				pmPrev != PM_PENALTY_SETUP_LEFT &&				WM->getPlayMode() == PM_PENALTY_SETUP_LEFT)			||			(WM->getSide() == SIDE_RIGHT &&			 pmPrev != PM_PENALTY_SETUP_RIGHT &&			 WM->getPlayMode() == PM_PENALTY_SETUP_RIGHT))		m_iPenaltyNr++;	// start with player 11 and go downwards with each new penalty	if (WM->isPenaltyUs()			&& WM->getPlayerNumber() == (11 - (m_iPenaltyNr % 11))) {		if (WM->getPlayMode() == PM_PENALTY_SETUP_LEFT ||				WM->getPlayMode() == PM_PENALTY_SETUP_RIGHT) {			// first move to position 2 meter before the penalty spot and there turn			// towards ball, then move on to the penalty spot			pos = posPenalty - VecPosition(iSide * 2.0, 0);			if (fabs(posAgent.getX()) > fabs(pos.getX()))				pos = posPenalty;			if (pos.getDistanceTo(posAgent) < 0.6) {				pos = posPenalty;				if (fabs(VecPosition::normalizeAngle((pos -									posAgent).								getDirection() -								angBody)) > 20)					soc = turnBodyToPoint(pos);			}		} else if (WM->getPlayMode() == PM_PENALTY_READY_LEFT ||				WM->getPlayMode() == PM_PENALTY_READY_RIGHT ||				WM->getPlayMode() == PM_PENALTY_TAKEN_LEFT ||				WM->getPlayMode() == PM_PENALTY_TAKEN_RIGHT) {			// if ball not kickable move to ball, otherwise always shoot to goal			if (SS->getPenAllowMultKicks() == false)				soc =					kickTo(VecPosition							(iSide * 52.5,							 ((drand48() < 0.5) ? 1 : -1) * 6.5),							SS->getBallSpeedMax());			else if (!WM->isBallKickable())				soc = intercept(false);			else				soc =					kickTo(VecPosition							(iSide * 52.5,							 ((drand48() < 0.5) ? 1 : -1) * 6.5),							SS->getBallSpeedMax());		} else			pos = posPenalty;	} else if (formations->getPlayerType() == PT_GOALKEEPER) {		// i am goalkeeper and penalty them		if (WM->isPenaltyThem()) {			//  set view to narrow			if (WM->getAgentViewAngle() != VA_NARROW)				ACT->					putCommandInQueue(SoccerCommand							(CMD_CHANGEVIEW, VA_NARROW,							 VQ_HIGH));			// if penalty has been taken and intercept or catch.			if (WM->getPlayMode() == PM_PENALTY_TAKEN_LEFT ||					WM->getPlayMode() == PM_PENALTY_TAKEN_RIGHT) {				if (WM->isBallCatchable())					soc = catchBall();				else					soc = intercept(true);			}			// else move to center of goal area and await ball			else {				double dLine =					PITCH_LENGTH / 2.0 - SS->getPenMaxGoalieDistX() + 0.5;				dLine *= iSide;				VecPosition pos(dLine, 0);				if (posAgent.getDistanceTo(pos) > 0.5)					soc = moveToPos(pos, 20);				else					soc =						turnBodyToPoint(posAgent +								VecPosition(1.0, 90, POLAR));			}		}		// if our penalty move to position outside of field		else {			if (WM->getAgentViewAngle() != VA_WIDE)				ACT->					putCommandInQueue(SoccerCommand							(CMD_CHANGEVIEW, VA_WIDE, VQ_HIGH));			pos.setVecPosition(iSide * (PITCH_LENGTH / 2.0 + 2), 25);		}	} else		pos = VecPosition(7.0,				VecPosition::normalizeAngle(iSide *					(50 +					 20 *					 WM->					 getPlayerNumber())),				POLAR);	if (soc.isIllegal() &&			WM->getAgentGlobalPosition().getDistanceTo(pos) < 0.8)

⌨️ 快捷键说明

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