?? player.c
字號:
/*Copyright (c) 2000-2002, Jelle Kok, University of AmsterdamAll rights reserved.Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University of Amsterdam nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*//*! \file Player.C<pre><b>File:</b> Player.C<b>Project:</b> Robocup Soccer Simulation Team: UvA Trilearn<b>Authors:</b> Jelle Kok<b>Created:</b> 03/03/2001<b>Last Revision:</b> $ID$<b>Contents:</b> This file contains the definitions for the Player class, which is a superclass from BasicPlayer and contains the decision procedure to select the skills from the BasicPlayer. <hr size=2><h2><b>Changes</b></h2><b>Date</b> <b>Author</b> <b>Comment</b>03/03/2001 Jelle Kok Initial version created</pre>*/#include "Player.h"#include "Parse.h"#include <sys/poll.h> // needed for 'poll'/*!This is the constructor the Player class and calls the constructor of the superclass BasicPlayer. \param act ActHandler to which the actions can be sent \param wm WorldModel which information is used to determine action \param ss ServerSettings that contain parameters used by the server \param ps PlayerSettings that contain parameters important for the client \param strTeamName team name of this player \param dVersion version this basicplayer corresponds to \param iReconnect integer that defines player number (-1 when new player) */Player::Player( ActHandler* act, WorldModel *wm, ServerSettings *ss, PlayerSettings *ps, Formations *fs, char* strTeamName, double dVersion, int iReconnect ){ char str[MAX_MSG]; ACT = act; WM = wm; SS = ss; PS = ps; formations = fs; bContLoop = true; WM->setTeamName( strTeamName ); m_timeLastSay = -5; // wait longer as role number increases, to make sure players appear at the // field in the correct order poll( 0, 0, formations->getPlayerInFormation()*100 ); // create initialisation string if( iReconnect != -1 ) sprintf( str, "(reconnect %s %d)", strTeamName, iReconnect ); else if( formations->getPlayerType() == PT_GOALKEEPER ) sprintf( str, "(init %s (version %f) (goalie))", strTeamName, dVersion ); else sprintf( str, "(init %s (version %f))", strTeamName, dVersion ); ACT->sendMessage( str );}/*! This is the main loop of the agent. This method calls the update methods of the world model after it is indicated that new information has arrived. After this, the correct main loop of the player type is called, which puts the best soccer command in the queue of the ActHandler. */void Player::mainLoop( ){ while( bContLoop ) // as long as server alive { Log.logWithTime( 3, " start update_all" ); Log.setHeader( WM->getCurrentCycle(), WM->getPlayerNumber() ); if( WM->updateAll( ) == true ) { if( shallISaySomething() == true ) // shall I communicate { m_timeLastSay = WM->getCurrentTime(); ACT->sendCommandDirect( sayBallStatus() ); } switch( formations->getPlayerType( ) ) // determine right loop { case PT_GOALKEEPER: goalieMainLoop( ); break; case PT_DEFENDER_SWEEPER: case PT_DEFENDER_WING: defenderMainLoop( ); break; case PT_MIDFIELDER_CENTER: case PT_MIDFIELDER_WING: midfielderMainLoop( ); break; case PT_ATTACKER: case PT_ATTACKER_WING: attackerMainLoop( ); break; case PT_ILLEGAL: default: break; } Log.logWithTime( 3, " determined action; waiting for new info" ); // directly after see message, will nog get better info, so send commands if( WM->getTimeLastSeeMessage() == WM->getCurrentTime() ) ACT->sendCommands( ); } else Log.logWithTime( 3, " HOLE no action determined; waiting for new info" ); // wait for new information from the server // cannot say bContLoop=WM->wait... since bContLoop can be changed elsewhere if( WM->waitForNewInformation() == false ) bContLoop = false; } // shutdow, print hole and number of players seen statistics printf("Shutting down player %d\n", WM->getPlayerNumber() ); printf(" Number of holes: %d (%f)\n", WM->iNrHoles, ((double)WM->iNrHoles/WM->getCurrentCycle())*100 ); printf(" Teammates seen: %d (%f)\n", WM->iNrTeammatesSeen, ((double)WM->iNrTeammatesSeen/WM->getCurrentCycle()) ); printf(" Opponents seen: %d (%f)\n", WM->iNrOpponentsSeen, ((double)WM->iNrOpponentsSeen/WM->getCurrentCycle()) );}/*! This is the main decision loop for the goalkeeper. */void Player::goalieMainLoop( ){ deMeer5_goalie();} /*! This is the main decision loop for a defender. */void Player::defenderMainLoop( ){ deMeer5() ;}/*! This is the main decision loop for a midfielder. */void Player::midfielderMainLoop( ){ deMeer5() ;}/*! This is the main decision loop for an agent. */void Player::attackerMainLoop( ){ deMeer5();}/*!This method is the first complete simple team and defines the actions taken by all the players on the field (excluding the goalie). It is based on the high-level actions taken by the simple team FC Portugal that it released in 2000. The players do the following: - if ball is kickable kick ball to goal (random corner of goal) - else if i am fastest player to ball and no opponent can intercept ball intercept the ball - else move to strategic position based on your home position and pos ball */void Player::deMeer5( ){ SoccerCommand soc(CMD_ILLEGAL); VecPosition posAgent = WM->getAgentGlobalPosition(); VecPosition posBall = WM->getBallPos(); int iTmp; if( WM->isKickOffThem( ) ) ; // do nothing else if( WM->isBeforeKickOff( ) ) { if( formations->getFormation() != FT_INITIAL ) formations->setFormation( FT_INITIAL ); // go to kick_off formation VecPosition posStrat = WM->getStrategicPosition(); if( WM->isKickOffThem( ) && posStrat.getDistanceTo( VecPosition(0,0) ) < 9.0 ) posStrat.setX( -10.0 ); if( posAgent.getDistanceTo( posStrat ) > 2.0 ) ACT->putCommandInQueue( teleportToPos( posStrat ) ); else // else turn to center { ACT->putCommandInQueue( turnBodyToPoint( VecPosition( 0, 0 ), 0 ) ); ACT->putCommandInQueue( alignNeckWithBody( ) ); } } else { formations->setFormation( FT_433_OFFENSIVE ); soc.commandType = CMD_ILLEGAL; if( WM->getConfidence( OBJECT_BALL ) < PS->getBallConfThr() ) { ACT->putCommandInQueue( searchBall() ); // if ball pos unknown ACT->putCommandInQueue( alignNeckWithBody( ) ); // search for it } else if( WM->isBallKickable()) // if kickable { VecPosition posGoal( PITCH_LENGTH/2.0, (-1 + 2*(WM->getCurrentCycle()%2)) * 0.4 * SS->getGoalWidth() ); soc = kickTo( posGoal, SS->getBallSpeedMax() ); // kick maximal ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); Log.log( 100, "kick ball" ); } else if( WM->getFastestInSetTo( OBJECT_SET_TEAMMATES, OBJECT_BALL, &iTmp ) == WM->getAgentObjectType() && !WM->isDeadBallThem() ) { // if fastest to ball Log.log( 100, "I am fastest to ball; can get there in %d cycles", iTmp ); soc = intercept( false ); // intercept the ball if( soc.commandType == CMD_DASH && // if stamina low WM->getAgentStamina().getStamina() < SS->getRecoverDecThr()*SS->getStaminaMax()+200 ) { soc.dPower = 30.0 * WM->getAgentStamina().getRecovery(); // dash slow ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } else // if stamina high { ACT->putCommandInQueue( soc ); // dash as intended ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } } else if( posAgent.getDistanceTo(WM->getStrategicPosition()) > 1.5 + fabs(posAgent.getX()-posBall.getX())/10.0) // if not near strategic pos { if( WM->getAgentStamina().getStamina() > // if stamina high SS->getRecoverDecThr()*SS->getStaminaMax()+200 ) { soc = moveToPos(WM->getStrategicPosition(),PS->getPlayerWhenToTurnAngle()); ACT->putCommandInQueue( soc ); // move to strategic pos ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } else // else watch ball { ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } } else if( fabs( WM->getRelativeAngle( OBJECT_BALL ) ) > 1.0 ) // watch ball { ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } else // nothing to do ACT->putCommandInQueue( SoccerCommand(CMD_TURNNECK,0.0) ); }}/*!This method is a simple goalie based on the goalie of the simple Team of FC Portugal. It defines a rectangle in its penalty area and moves to the position on this rectangle where the ball intersects if you make a line between the ball position and the center of the goal. If the ball can be intercepted in the own penalty area the ball is intercepted and catched.*/void Player::deMeer5_goalie( ){ int i; SoccerCommand soc; VecPosition posAgent = WM->getAgentGlobalPosition(); AngDeg angBody = WM->getAgentGlobalBodyAngle(); // define the top and bottom position of a rectangle in which keeper moves static const VecPosition posLeftTop( -PITCH_LENGTH/2.0 + 0.7*PENALTY_AREA_LENGTH, -PENALTY_AREA_WIDTH/4.0 ); static const VecPosition posRightTop( -PITCH_LENGTH/2.0 + 0.7*PENALTY_AREA_LENGTH, +PENALTY_AREA_WIDTH/4.0 ); // define the borders of this rectangle using the two points. static Line lineFront = Line::makeLineFromTwoPoints(posLeftTop, posRightTop); static Line lineLeft = Line::makeLineFromTwoPoints( VecPosition( -50.0, posLeftTop.getY()), posLeftTop ); static Line lineRight = Line::makeLineFromTwoPoints( VecPosition( -50.0, posRightTop.getY()),posRightTop ); 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 ) ); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -