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

Formations.C

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000-2002, 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 */
00047 #include "Formations.h"
00048 #include "Parse.h"       // Parse
00049 
00050 #include <fstream.h>     // ifstream
00051 #include <stdio.h>       // printf
00052 #include <math.h>        // fabs
00053 
00054 /******************************************************************************/
00055 /********************** CLASS PLAYERTYPEINFO **********************************/
00056 /******************************************************************************/
00057 
00063 PlayerTypeInfo::PlayerTypeInfo()
00064 {
00065   setValues( PT_ILLEGAL, UnknownDoubleValue,UnknownDoubleValue,
00066              UnknownDoubleValue, UnknownDoubleValue, false);
00067 }
00068 
00078 PlayerTypeInfo::PlayerTypeInfo( PlayerT pt, double dAttrX, double dAttrY,
00079                                 double dMinX, double dMaxX, bool bBehindBall )
00080 {
00081   setValues( pt, dAttrX, dAttrY, dMinX, dMaxX, bBehindBall );
00082 }
00083 
00094 bool PlayerTypeInfo::setValues( PlayerT pt,   double ax,   double ay,
00095                                 double minx,  double maxx, bool bb)
00096 {
00097   playerType  = pt;
00098   dAttrX      = ax;
00099   dAttrY      = ay;
00100   dMinX       = minx;
00101   dMaxX       = maxx;
00102   bBehindBall = bb;
00103 
00104   return true;
00105 }
00106 
00110 void PlayerTypeInfo::show( ostream &os )
00111 {
00112   os << "(" << (int)playerType << ", " << dAttrX << ", " << dAttrY << ", "
00113             << dMinX           << ", " << dMaxX  << ", " << bBehindBall << ")"
00114             << endl;
00115 
00116 }
00117 
00121 bool PlayerTypeInfo::setPlayerType( PlayerT type )
00122 {
00123   playerType = type;
00124   return true;
00125 }
00126 
00129 PlayerT PlayerTypeInfo::getPlayerType( ) const
00130 {
00131   return playerType;
00132 }
00133 
00142 bool PlayerTypeInfo::setAttrX( double dAttractionX )
00143 {
00144   dAttrX = dAttractionX;
00145   return true;
00146 }
00147 
00155 double PlayerTypeInfo::getAttrX( ) const
00156 {
00157   return dAttrX;
00158 }
00159 
00168 bool PlayerTypeInfo::setAttrY( double dAttractionY )
00169 {
00170   dAttrY = dAttractionY;
00171   return true;
00172 }
00173 
00181 double PlayerTypeInfo::getAttrY( ) const
00182 {
00183   return dAttrY;
00184 }
00185 
00191 bool PlayerTypeInfo::setMinX( double dMinimalX )
00192 {
00193   dMinX = dMinimalX;
00194   return true;
00195 }
00196 
00201 double PlayerTypeInfo::getMinX( ) const
00202 {
00203   return dMinX;
00204 }
00205 
00211 bool PlayerTypeInfo::setMaxX( double dMaximalX )
00212 {
00213   dMaxX = dMaximalX;
00214   return true;
00215 }
00216 
00221 double PlayerTypeInfo::getMaxX( ) const
00222 {
00223   return dMaxX;
00224 }
00225 
00233 bool PlayerTypeInfo::setBehindBall( bool b )
00234 {
00235   bBehindBall = b;
00236   return true;
00237 }
00238 
00245 bool PlayerTypeInfo::getBehindBall( ) const
00246 {
00247   return bBehindBall;
00248 }
00249 
00250 /******************************************************************************/
00251 /********************** CLASS FORMATIONTYPEINFO********************************/
00252 /******************************************************************************/
00253 
00255 FormationTypeInfo::FormationTypeInfo( )
00256 {
00257 }
00258 
00262 bool FormationTypeInfo::setFormationType( FormationT type )
00263 {
00264   formationType = type;
00265   return true;
00266 }
00267 
00270 FormationT FormationTypeInfo::getFormationType( ) const
00271 {
00272   return formationType;
00273 }
00274 
00286 void FormationTypeInfo::show( ostream &os )
00287 {
00288   char str[128];
00289   for( int i = 0; i < MAX_TEAMMATES; i++ )
00290   {
00291     sprintf(str, "%3.2f ", posHome[i].getX() );
00292     os << str;
00293   }
00294   os << endl;
00295   for( int i = 0; i < MAX_TEAMMATES; i++ )
00296   {
00297     sprintf( str, "%3.2f ", posHome[i].getY() );
00298     os << str;
00299   }
00300   os << endl;
00301   for( int i = 0; i < MAX_TEAMMATES; i++ )
00302   {
00303     sprintf( str, "%5d ", (int)playerType[i] );
00304     os << str;
00305   }
00306   os << endl;
00307   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00308   {
00309     sprintf( str, "%3.2f ", playerTypeInfo[i].getAttrX() );
00310     os << str;
00311   }
00312   os << endl;
00313   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00314   {
00315     sprintf( str, "%3.2f ", playerTypeInfo[i].getAttrY() );
00316     os << str;
00317   }
00318   os << endl;
00319   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00320   {
00321     sprintf( str, "%5d ", playerTypeInfo[i].getBehindBall() );
00322     os << str;
00323   }
00324   os << endl;
00325   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00326   {
00327     sprintf( str, "%3.2f ", playerTypeInfo[i].getMinX() );
00328     os << str;
00329   }
00330   os << endl;
00331   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00332   {
00333     sprintf( str, "%3.2f ", playerTypeInfo[i].getMaxX() );
00334     os << str;
00335   }
00336   os << endl;
00337 }
00338 
00339 
00348 bool FormationTypeInfo::setPosHome( VecPosition pos, int atIndex )
00349 {
00350   posHome[ atIndex ] = pos;
00351   return true;
00352 }
00353 
00359 bool FormationTypeInfo::setXPosHome( double x, int atIndex )
00360 {
00361   posHome[ atIndex ].setX( x );
00362   return true;
00363 }
00364 
00370 bool FormationTypeInfo::setYPosHome( double y, int atIndex )
00371 {
00372   posHome[ atIndex ].setY( y );
00373   return true;
00374 }
00375 
00381 VecPosition FormationTypeInfo::getPosHome( int atIndex ) const
00382 {
00383   return posHome[ atIndex ];
00384 }
00385 
00391 bool FormationTypeInfo::setPlayerType( PlayerT type, int atIndex )
00392 {
00393   playerType[ atIndex ] = type;
00394   return true;
00395 }
00396 
00400 PlayerT FormationTypeInfo::getPlayerType( int atIndex ) const
00401 {
00402   return playerType[ atIndex ];
00403 }
00404 
00410 bool FormationTypeInfo::setPlayerTypeInfo( PlayerTypeInfo info, int atIndex )
00411 {
00412   playerTypeInfo[ atIndex ] = info;
00413   return true;
00414 }
00415 
00420 PlayerTypeInfo* FormationTypeInfo::getPlayerTypeInfo( int atIndex )
00421 {
00422   return &playerTypeInfo[ atIndex ];
00423 }
00424 
00425 
00430 PlayerTypeInfo* FormationTypeInfo::getPlayerTypeInfoOfPlayer(
00431                                                        int iPlayerInFormation )
00432 {
00433   return &playerTypeInfo[ playerType[iPlayerInFormation] ];
00434 }
00435 
00436 /******************************************************************************/
00437 /********************** CLASS FORMATIONS **************************************/
00438 /******************************************************************************/
00439 
00447 Formations::Formations( const char *strFile, FormationT curFt, int iNr )
00448 {
00449   if( strFile == NULL )
00450   {
00451     cerr << "(Formations::Formations) No Filename given" << endl;
00452     return;
00453   }
00454 
00455   if( readFormations( strFile ) == false )
00456     cerr << "(Formations::Formations) Error reading file" << endl;
00457   curFormation = curFt;
00458   setPlayerInFormation( iNr );
00459 }
00460 
00465 void Formations::show( ostream &os )
00466 {
00467   for( int i = 0 ; i < MAX_FORMATION_TYPES; i ++ )
00468     formations[i].show( os );
00469   os << "Current formation: " << (int)curFormation << endl
00470        << "Player nr in formation: " << iPlayerInFormation ;
00471 }
00472 
00492 VecPosition Formations::getStrategicPosition( int iPlayer, VecPosition posBall,
00493                   double dMaxXInPlayMode )
00494 {
00495   VecPosition     posHome;
00496   PlayerTypeInfo* ptInfo = formations[curFormation].
00497                             getPlayerTypeInfoOfPlayer( iPlayer );
00498   double x, y;
00499 
00500   // get the home position and calculate the associated strategic position
00501   posHome = formations[curFormation].getPosHome( iPlayer );
00502   y = posHome.getY() + posBall.getY() * ptInfo->getAttrY();
00503   x = posHome.getX() + posBall.getX() * ptInfo->getAttrX();
00504 
00505   // do not move to much to the side
00506   if( fabs( y ) > 0.5*0.75*PITCH_WIDTH )
00507     y -= 0.5*posBall.getY() * ptInfo->getAttrY();
00508 
00509   // when behind ball is set, do not move to point in front of ball
00510   if( ptInfo->getBehindBall() == true && x > posBall.getX() )
00511     x = posBall.getX();
00512 
00513   // do not move past maximal x or before minimal x
00514   if( x > ptInfo->getMaxX() )
00515     x = ptInfo->getMaxX();
00516   else if( x < ptInfo->getMinX() )
00517     x = ptInfo->getMinX();
00518 
00519   // when x coordinate is in front of allowed x value, change it
00520   if( x > dMaxXInPlayMode )
00521     x = dMaxXInPlayMode;
00522 
00523   return VecPosition( x, y );
00524 }
00525 
00538 bool Formations::readFormations( const char *strFile )
00539 {
00540   ifstream in( strFile );
00541   if( !in )
00542   {
00543     cerr << "(readValues::readValues) Could not open file '" <<
00544     strFile << "'" << endl;
00545     return false;
00546   }
00547 
00548   char strLine[256], *str;
00549   int            iLineNr          = 0, i;
00550   int            iForm            = 0; // current formation type that is parsed
00551   int            iLineInFormation = 0; // current offset of line in formation
00552   bool           bReturn          = true;
00553   PlayerTypeInfo *pt_info;
00554 
00555   // read all lines
00556   while( bReturn && in.getline( strLine, sizeof(strLine) ) )
00557   {
00558     str = &strLine[0];
00559     iLineNr++;
00560     // comment and empty lines should be skipped
00561     if( !(strLine[0] == '\n' || strLine[0] == '#' || strLine[0]=='\0' ||
00562           Parse::gotoFirstNonSpace( &str ) == '\0' ) )
00563     {
00564       // there are nine different lines in a formation (see comment above)
00565       // all values for each line are parsed in one iteration
00566       // after all 9 lines are parsed, the sequence it is resetted.
00567       switch( iLineInFormation )
00568       {
00569         case 0: // first line is the number of the formation
00570           iForm = Parse::parseFirstInt( &str );
00571           break;
00572         case 1: // the x coordinate of the home pos for all the players
00573           for( i = 0 ; i < MAX_TEAMMATES ; i ++ )
00574             formations[iForm].setXPosHome(Parse::parseFirstDouble(&str), i);
00575           break;
00576         case 2: // the y coordinate of the home pos for all the players
00577           for( i = 0 ; i < MAX_TEAMMATES ; i ++ )
00578             formations[iForm].setYPosHome(Parse::parseFirstDouble(&str), i);
00579           break;
00580         case 3: // the player types for all the players
00581           for( i = 0 ; i < MAX_TEAMMATES ; i ++ )
00582             formations[iForm].setPlayerType(
00583                 (PlayerT) Parse::parseFirstInt(&str), i);
00584           break;
00585         case 4: // the x attraction for all the player types
00586           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00587           {
00588             pt_info = formations[iForm].getPlayerTypeInfo( i );
00589             pt_info->setAttrX( Parse::parseFirstDouble( &str ) );
00590           }
00591           break;
00592         case 5: // the y attraction for all the player types
00593           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00594           {
00595             pt_info = formations[iForm].getPlayerTypeInfo( i );
00596             pt_info->setAttrY( Parse::parseFirstDouble( &str ) );
00597           }
00598           break;
00599         case 6: // stay behind the ball for all the player types
00600           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00601           {
00602             pt_info = formations[iForm].getPlayerTypeInfo( i );
00603             if( Parse::parseFirstInt( &str ) == 1 )
00604               pt_info->setBehindBall( true );
00605             else
00606               pt_info->setBehindBall( false );          ;
00607           }
00608           break;
00609         case 7: // the minimal x coordinate for all the player types
00610           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00611           {
00612             pt_info = formations[iForm].getPlayerTypeInfo( i );
00613             pt_info->setMinX( Parse::parseFirstDouble( &str ));
00614           }
00615           break;
00616         case 8:// the maximal x coordinate for all the player types
00617           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00618           {
00619             pt_info = formations[iForm].getPlayerTypeInfo( i );
00620             pt_info->setMaxX( Parse::parseFirstDouble( &str ));
00621           }
00622           break;
00623         default:
00624           cerr << "(Formations::readFormations) error line " << iLineNr <<endl;
00625           return false;
00626       }
00627 
00628       iLineInFormation++;         // go one line further
00629       if( iLineInFormation == 9 ) // each formation consists of nine lines
00630         iLineInFormation = 0;
00631     }
00632   }
00633   return true;
00634 }
00635 
00639 bool Formations::setFormation( FormationT formation )
00640 {
00641   curFormation = formation;
00642   return true;
00643 }
00644 
00647 FormationT Formations::getFormation( ) const
00648 {
00649   return curFormation;
00650 }
00651 
00656 bool Formations::setPlayerInFormation( int iNumber )
00657 {
00658   iPlayerInFormation = iNumber;
00659   return true;
00660 }
00661 
00664 int Formations::getPlayerInFormation( ) const
00665 {
00666   return iPlayerInFormation;
00667 }
00668 
00671 PlayerT Formations::getPlayerType( int iIndex ) const
00672 {
00673   if( iIndex == -1  )
00674     iIndex = iPlayerInFormation;
00675   return formations[ curFormation ].getPlayerType( iIndex );
00676 }
00677 
00678 /*************************** TESTING PURPOSES *********************************/
00679 
00680 /*
00681 int main( void )
00682 {
00683   Formations fs( "formations.conf" );
00684   fs.show( cout );
00685 }
00686 */

Generated on Tue Jul 2 10:18:51 2002 for UvA Trilearn 2002 by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001