Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Formations.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000-2003, Jelle Kok, University of Amsterdam
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007 
00008 1. Redistributions of source code must retain the above copyright notice, this
00009 list of conditions and the following disclaimer.
00010 
00011 2. Redistributions in binary form must reproduce the above copyright notice,
00012 this list of conditions and the following disclaimer in the documentation
00013 and/or other materials provided with the distribution.
00014 
00015 3. Neither the name of the University of Amsterdam nor the names of its
00016 contributors may be used to endorse or promote products derived from this
00017 software without specific prior written permission.
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
00023 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00024 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00025 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00026 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00027 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00028 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 */
00030 
00048 #include "Formations.h"
00049 #include "Parse.h"       // Parse
00050 
00051 #include <fstream>       // ifstream
00052 #include <stdio.h>       // printf
00053 #include <math.h>        // fabs
00054 
00055 /*****************************************************************************/
00056 /********************** CLASS PLAYERTYPEINFO *********************************/
00057 /*****************************************************************************/
00058 
00064 PlayerTypeInfo::PlayerTypeInfo()
00065 {
00066   setValues( PT_ILLEGAL, UnknownDoubleValue,UnknownDoubleValue,
00067              UnknownDoubleValue,UnknownDoubleValue, false );
00068 }
00069 
00079 PlayerTypeInfo::PlayerTypeInfo( PlayerT pt, double dAttrX, double dAttrY,
00080               double dMinX, double dMaxX, bool bBehindBall  )
00081 {
00082   setValues( pt, dAttrX, dAttrY, dMinX, dMaxX, bBehindBall );
00083 }
00084 
00095 bool PlayerTypeInfo::setValues( PlayerT pt,   double ax,   double ay,
00096                           double minx,  double maxx, bool bb )
00097 {
00098   playerType      = pt;
00099   dAttrX          = ax;
00100   dAttrY          = ay;
00101   dMinX           = minx;
00102   dMaxX           = maxx;
00103   bBehindBall     = bb;
00104 
00105   return true;
00106 }
00107 
00111 void PlayerTypeInfo::show( ostream &os )
00112 {
00113   os << "(" << (int)playerType << ", " << dAttrX << ", " << dAttrY << ", "
00114             << dMinX           << ", " << dMaxX  << ", " << bBehindBall 
00115             <<  ")" << endl;
00116 
00117 }
00118 
00122 bool PlayerTypeInfo::setPlayerType( PlayerT type )
00123 {
00124   playerType = type;
00125   return true;
00126 }
00127 
00130 PlayerT PlayerTypeInfo::getPlayerType( ) const
00131 {
00132   return playerType;
00133 }
00134 
00143 bool PlayerTypeInfo::setAttrX( double dAttractionX )
00144 {
00145   dAttrX = dAttractionX;
00146   return true;
00147 }
00148 
00156 double PlayerTypeInfo::getAttrX( ) const
00157 {
00158   return dAttrX;
00159 }
00160 
00169 bool PlayerTypeInfo::setAttrY( double dAttractionY )
00170 {
00171   dAttrY = dAttractionY;
00172   return true;
00173 }
00174 
00182 double PlayerTypeInfo::getAttrY( ) const
00183 {
00184   return dAttrY;
00185 }
00186 
00192 bool PlayerTypeInfo::setMinX( double dMinimalX )
00193 {
00194   dMinX = dMinimalX;
00195   return true;
00196 }
00197 
00202 double PlayerTypeInfo::getMinX( ) const
00203 {
00204   return dMinX;
00205 }
00206 
00212 bool PlayerTypeInfo::setMaxX( double dMaximalX )
00213 {
00214   dMaxX = dMaximalX;
00215   return true;
00216 }
00217 
00222 double PlayerTypeInfo::getMaxX( ) const
00223 {
00224   return dMaxX;
00225 }
00226 
00234 bool PlayerTypeInfo::setBehindBall( bool b )
00235 {
00236   bBehindBall = b;
00237   return true;
00238 }
00239 
00246 bool PlayerTypeInfo::getBehindBall( ) const
00247 {
00248   return bBehindBall;
00249 }
00250 
00251 /*****************************************************************************/
00252 /********************** CLASS FORMATIONTYPEINFO*******************************/
00253 /*****************************************************************************/
00254 
00256 FormationTypeInfo::FormationTypeInfo( )
00257 {
00258 }
00259 
00263 bool FormationTypeInfo::setFormationType( FormationT type )
00264 {
00265   formationType = type;
00266   return true;
00267 }
00268 
00271 FormationT FormationTypeInfo::getFormationType( ) const
00272 {
00273   return formationType;
00274 }
00275 
00287 void FormationTypeInfo::show( ostream &os )
00288 {
00289   char str[128];
00290   for( int i = 0; i < MAX_TEAMMATES; i++ )
00291   {
00292     sprintf(str, "%3.2f ", posHome[i].getX() );
00293     os << str;
00294   }
00295   os << endl;
00296   for( int i = 0; i < MAX_TEAMMATES; i++ )
00297   {
00298     sprintf( str, "%3.2f ", posHome[i].getY() );
00299     os << str;
00300   }
00301   os << endl;
00302   for( int i = 0; i < MAX_TEAMMATES; i++ )
00303   {
00304     sprintf( str, "%5d ", (int)playerType[i] );
00305     os << str;
00306   }
00307   os << endl;
00308   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00309   {
00310     sprintf( str, "%3.2f ", playerTypeInfo[i].getAttrX() );
00311     os << str;
00312   }
00313   os << endl;
00314   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00315   {
00316     sprintf( str, "%3.2f ", playerTypeInfo[i].getAttrY() );
00317     os << str;
00318   }
00319   os << endl;
00320   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00321   {
00322     sprintf( str, "%5d ", playerTypeInfo[i].getBehindBall() );
00323     os << str;
00324   }
00325   os << endl;
00326   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00327   {
00328     sprintf( str, "%3.2f ", playerTypeInfo[i].getMinX() );
00329     os << str;
00330   }
00331   os << endl;
00332   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00333   {
00334     sprintf( str, "%3.2f ", playerTypeInfo[i].getMaxX() );
00335     os << str;
00336   }
00337   os << endl;
00338 }
00339 
00340 
00349 bool FormationTypeInfo::setPosHome( VecPosition pos, int atIndex )
00350 {
00351   posHome[ atIndex ] = pos;
00352   return true;
00353 }
00354 
00360 bool FormationTypeInfo::setXPosHome( double x, int atIndex )
00361 {
00362   posHome[ atIndex ].setX( x );
00363   return true;
00364 }
00365 
00371 bool FormationTypeInfo::setYPosHome( double y, int atIndex )
00372 {
00373   posHome[ atIndex ].setY( y );
00374   return true;
00375 }
00376 
00382 VecPosition FormationTypeInfo::getPosHome( int atIndex ) const
00383 {
00384   return posHome[ atIndex ];
00385 }
00386 
00392 bool FormationTypeInfo::setPlayerType( PlayerT type, int atIndex )
00393 {
00394   playerType[ atIndex ] = type;
00395   return true;
00396 }
00397 
00401 PlayerT FormationTypeInfo::getPlayerType( int atIndex ) const
00402 {
00403   return playerType[ atIndex ];
00404 }
00405 
00411 bool FormationTypeInfo::setPlayerTypeInfo( PlayerTypeInfo info, int atIndex )
00412 {
00413   playerTypeInfo[ atIndex ] = info;
00414   return true;
00415 }
00416 
00421 PlayerTypeInfo* FormationTypeInfo::getPlayerTypeInfo( int atIndex )
00422 {
00423   return &playerTypeInfo[ atIndex ];
00424 }
00425 
00426 
00431 PlayerTypeInfo* FormationTypeInfo::getPlayerTypeInfoOfPlayer(
00432                                                        int iPlayerInFormation )
00433 {
00434   return &playerTypeInfo[ playerType[iPlayerInFormation] ];
00435 }
00436 
00437 /*****************************************************************************/
00438 /********************** CLASS FORMATIONS *************************************/
00439 /*****************************************************************************/
00440 
00448 Formations::Formations( const char *strFile, FormationT curFt, int iNr )
00449 {
00450   if( strFile[0] == '\0' )
00451   {
00452     cerr << "(Formations::Formations) No Filename given" << endl;
00453     return;
00454   }
00455 
00456   if( readFormations( strFile ) == false )
00457     cerr << "(Formations::Formations) Error reading file " << strFile << endl;
00458   curFormation = curFt;
00459   setPlayerInFormation( iNr );
00460 }
00461 
00466 void Formations::show( ostream &os )
00467 {
00468   for( int i = 0 ; i < MAX_FORMATION_TYPES; i ++ )
00469     formations[i].show( os );
00470   os << "Current formation: " << (int)curFormation << endl
00471        << "Player nr in formation: " << iPlayerInFormation ;
00472 }
00473 
00493 VecPosition Formations::getStrategicPosition( int iPlayer, VecPosition posBall,
00494      double dMaxXInPlayMode, bool bInBallPossession, double dMaxYPercentage,
00495      FormationT ft )
00496 {
00497   if( ft == FT_ILLEGAL )
00498     ft = curFormation;
00499   VecPosition     posHome;
00500   PlayerTypeInfo* ptInfo = formations[ft].
00501                             getPlayerTypeInfoOfPlayer( iPlayer );
00502   double x, y;
00503 
00504   // get the home position and calculate the associated strategic position
00505   posHome = formations[ft].getPosHome( iPlayer );
00506   y = posHome.getY() + posBall.getY() * ptInfo->getAttrY();
00507   x = posHome.getX() + posBall.getX() * ptInfo->getAttrX();
00508 
00509   // do not move too much to the side
00510   if( fabs( y ) > 0.5*dMaxYPercentage*PITCH_WIDTH )
00511     y = sign(y)*0.5*dMaxYPercentage*PITCH_WIDTH;
00512 
00513   // when behind ball is set, do not move to point in front of ball
00514   if( ptInfo->getBehindBall() == true && x > posBall.getX() )
00515     x = posBall.getX();
00516 
00517   // do not move past maximal x or before minimal x
00518   if( x > ptInfo->getMaxX() )
00519     x = ptInfo->getMaxX();
00520   else if( x < ptInfo->getMinX() )
00521     x = ptInfo->getMinX();
00522 
00523   // when x coordinate is in front of allowed x value, change it
00524   if( x > dMaxXInPlayMode )
00525     x = dMaxXInPlayMode;
00526 
00527   return VecPosition( x, y );
00528 }
00529 
00543 bool Formations::readFormations( const char *strFile )
00544 {
00545   ifstream in( strFile );
00546   if( !in )
00547   {
00548     cerr << "(readValues::readValues) Could not open file '" <<
00549     strFile << "'" << endl;
00550     return false;
00551   }
00552 
00553   char strLine[256], *str;
00554   int            iLineNr          = 0, i;
00555   int            iForm            = 0; // current formation type that is parsed
00556   int            iLineInFormation = 0; // current offset of line in formation
00557   bool           bReturn          = true;
00558   PlayerTypeInfo *pt_info;
00559 
00560   // read all lines
00561   while( bReturn && in.getline( strLine, sizeof(strLine) ) )
00562   {
00563     str = &strLine[0];
00564     iLineNr++;
00565     // comment and empty lines should be skipped
00566     if( !(strLine[0] == '\n' || strLine[0] == '#' || strLine[0]=='\0' ||
00567           Parse::gotoFirstNonSpace( &str ) == '\0' ) )
00568     {
00569       // there are ten different lines in a formation (see comment above)
00570       // all values for each line are parsed in one iteration
00571       // after all 10 lines are parsed, the sequence it is resetted.
00572       switch( iLineInFormation )
00573       {
00574         case 0: // first line is the number of the formation
00575           iForm = Parse::parseFirstInt( &str );
00576           break;
00577         case 1: // the x coordinate of the home pos for all the players
00578           for( i = 0 ; i < MAX_TEAMMATES ; i ++ )
00579             formations[iForm].setXPosHome(Parse::parseFirstDouble(&str), i);
00580           break;
00581         case 2: // the y coordinate of the home pos for all the players
00582           for( i = 0 ; i < MAX_TEAMMATES ; i ++ )
00583             formations[iForm].setYPosHome(Parse::parseFirstDouble(&str), i);
00584           break;
00585         case 3: // the player types for all the players
00586           for( i = 0 ; i < MAX_TEAMMATES ; i ++ )
00587             formations[iForm].setPlayerType(
00588                 (PlayerT) Parse::parseFirstInt(&str), i);
00589           break;
00590         case 4: // the x attraction for all the player types
00591           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00592           {
00593             pt_info = formations[iForm].getPlayerTypeInfo( i );
00594             pt_info->setAttrX( Parse::parseFirstDouble( &str ) );
00595           }
00596           break;
00597         case 5: // the y attraction for all the player types
00598           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00599           {
00600             pt_info = formations[iForm].getPlayerTypeInfo( i );
00601             pt_info->setAttrY( Parse::parseFirstDouble( &str ) );
00602           }
00603           break;
00604         case 6: // stay behind the ball for all the player types
00605           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00606           {
00607             pt_info = formations[iForm].getPlayerTypeInfo( i );
00608             if( Parse::parseFirstInt( &str ) == 1 )
00609               pt_info->setBehindBall( true );
00610             else
00611               pt_info->setBehindBall( false );          ;
00612           }
00613           break;
00614         case 7: // the minimal x coordinate for all the player types
00615           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00616           {
00617             pt_info = formations[iForm].getPlayerTypeInfo( i );
00618             pt_info->setMinX( Parse::parseFirstDouble( &str ));
00619           }
00620           break;
00621         case 8:// the maximal x coordinate for all the player types
00622           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00623           {
00624             pt_info = formations[iForm].getPlayerTypeInfo( i );
00625             pt_info->setMaxX( Parse::parseFirstDouble( &str ));
00626           }
00627           break;
00628         default:
00629           cerr << "(Formations::readFormations) error line " << iLineNr <<endl;
00630           return false;
00631       }
00632 
00633       iLineInFormation++;          // go one line further
00634       if( iLineInFormation == 9 ) // each formation consists of ten lines
00635         iLineInFormation = 0;
00636     }
00637   }
00638   return true;
00639 }
00640 
00644 bool Formations::setFormation( FormationT formation )
00645 {
00646   curFormation = formation;
00647   return true;
00648 }
00649 
00652 FormationT Formations::getFormation( ) const
00653 {
00654   return curFormation;
00655 }
00656 
00661 bool Formations::setPlayerInFormation( int iNumber )
00662 {
00663   iPlayerInFormation = iNumber;
00664   return true;
00665 }
00666 
00669 int Formations::getPlayerInFormation( ObjectT obj  ) const
00670 {
00671   int i;
00672   if( obj == OBJECT_ILLEGAL )
00673     i = iPlayerInFormation;
00674   else
00675     i = SoccerTypes::getIndex( obj );
00676 
00677   return i;
00678 }
00679 
00682 PlayerT Formations::getPlayerType( ObjectT obj, FormationT ft ) const
00683 {
00684   if( ft == FT_ILLEGAL )
00685     ft = curFormation;
00686   return formations[ ft ].getPlayerType( 
00687     SoccerTypes::getIndex( obj ) );
00688 }
00689 
00692 PlayerT Formations::getPlayerType( int iIndex, FormationT ft ) const
00693 {
00694   if( ft == FT_ILLEGAL )
00695     ft = curFormation;
00696   if( iIndex == -1  )
00697     iIndex = iPlayerInFormation;
00698   return formations[ ft ].getPlayerType( iIndex );
00699 }
00700 
00701 /*************************** TESTING PURPOSES ********************************/
00702 
00703 /*
00704 int main( void )
00705 {
00706   Formations fs( "formations.conf" );
00707   fs.show( cout );
00708 }
00709 */

Generated on Fri Nov 7 11:45:39 2003 for UvA Trilearn 2003 Base Code by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001