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,2001, 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 */
00043 #include "Formations.h"
00044 #include "Parse.h"       // Parse
00045 
00046 #include <fstream.h>     // ifstream
00047 #include <stdio.h>       // printf
00048 #include <math.h>        // fabs
00049 
00050 /******************************************************************************/
00051 /********************** CLASS PLAYERTYPEINFO **********************************/
00052 /******************************************************************************/
00053 
00059 PlayerTypeInfo::PlayerTypeInfo()
00060 {
00061   setValues( PT_ILLEGAL, UnknownDoubleValue,UnknownDoubleValue,
00062              UnknownDoubleValue, UnknownDoubleValue, false);
00063 }
00064 
00074 PlayerTypeInfo::PlayerTypeInfo( PlayerT pt, double dAttrX, double dAttrY,
00075                                 double dMinX, double dMaxX, bool bBehindBall )
00076 {
00077   setValues( pt, dAttrX, dAttrY, dMinX, dMaxX, bBehindBall );
00078 }
00079 
00090 bool PlayerTypeInfo::setValues( PlayerT pt,   double ax,   double ay,
00091                                 double minx,  double maxx, bool bb)
00092 {
00093   playerType  = pt;
00094   dAttrX      = ax;
00095   dAttrY      = ay;
00096   dMinX       = minx;
00097   dMaxX       = maxx;
00098   bBehindBall = bb;
00099 
00100   return true;
00101 }
00102 
00106 void PlayerTypeInfo::show( ostream &os )
00107 {
00108   os << "(" << (int)playerType << ", " << dAttrX << ", " << dAttrY << ", "
00109             << dMinX           << ", " << dMaxX  << ", " << bBehindBall << ")"
00110             << endl;
00111 
00112 }
00113 
00117 bool PlayerTypeInfo::setPlayerType( PlayerT type )
00118 {
00119   playerType = type;
00120   return true;
00121 }
00122 
00125 PlayerT PlayerTypeInfo::getPlayerType( ) const
00126 {
00127   return playerType;
00128 }
00129 
00138 bool PlayerTypeInfo::setAttrX( double dAttractionX )
00139 {
00140   dAttrX = dAttractionX;
00141   return true;
00142 }
00143 
00151 double PlayerTypeInfo::getAttrX( ) const
00152 {
00153   return dAttrX;
00154 }
00155 
00164 bool PlayerTypeInfo::setAttrY( double dAttractionY )
00165 {
00166   dAttrY = dAttractionY;
00167   return true;
00168 }
00169 
00177 double PlayerTypeInfo::getAttrY( ) const
00178 {
00179   return dAttrY;
00180 }
00181 
00187 bool PlayerTypeInfo::setMinX( double dMinimalX )
00188 {
00189   dMinX = dMinimalX;
00190   return true;
00191 }
00192 
00197 double PlayerTypeInfo::getMinX( ) const
00198 {
00199   return dMinX;
00200 }
00201 
00207 bool PlayerTypeInfo::setMaxX( double dMaximalX )
00208 {
00209   dMaxX = dMaximalX;
00210   return true;
00211 }
00212 
00217 double PlayerTypeInfo::getMaxX( ) const
00218 {
00219   return dMaxX;
00220 }
00221 
00229 bool PlayerTypeInfo::setBehindBall( bool b )
00230 {
00231   bBehindBall = b;
00232   return true;
00233 }
00234 
00241 bool PlayerTypeInfo::getBehindBall( ) const
00242 {
00243   return bBehindBall;
00244 }
00245 
00246 /******************************************************************************/
00247 /********************** CLASS FORMATIONTYPEINFO********************************/
00248 /******************************************************************************/
00249 
00251 FormationTypeInfo::FormationTypeInfo( )
00252 {
00253 }
00254 
00258 bool FormationTypeInfo::setFormationType( FormationT type )
00259 {
00260   formationType = type;
00261   return true;
00262 }
00263 
00266 FormationT FormationTypeInfo::getFormationType( ) const
00267 {
00268   return formationType;
00269 }
00270 
00282 void FormationTypeInfo::show( ostream &os )
00283 {
00284   char str[128];
00285   for( int i = 0; i < MAX_TEAMMATES; i++ )
00286   {
00287     sprintf(str, "%3.2f ", posHome[i].getX() );
00288     os << str;
00289   }
00290   os << endl;
00291   for( int i = 0; i < MAX_TEAMMATES; i++ )
00292   {
00293     sprintf( str, "%3.2f ", posHome[i].getY() );
00294     os << str;
00295   }
00296   os << endl;
00297   for( int i = 0; i < MAX_TEAMMATES; i++ )
00298   {
00299     sprintf( str, "%5d ", (int)playerType[i] );
00300     os << str;
00301   }
00302   os << endl;
00303   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00304   {
00305     sprintf( str, "%3.2f ", playerTypeInfo[i].getAttrX() );
00306     os << str;
00307   }
00308   os << endl;
00309   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00310   {
00311     sprintf( str, "%3.2f ", playerTypeInfo[i].getAttrY() );
00312     os << str;
00313   }
00314   os << endl;
00315   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00316   {
00317     sprintf( str, "%5d ", playerTypeInfo[i].getBehindBall() );
00318     os << str;
00319   }
00320   os << endl;
00321   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00322   {
00323     sprintf( str, "%3.2f ", playerTypeInfo[i].getMinX() );
00324     os << str;
00325   }
00326   os << endl;
00327   for( int i = 0; i < MAX_PLAYER_TYPES; i++ )
00328   {
00329     sprintf( str, "%3.2f ", playerTypeInfo[i].getMaxX() );
00330     os << str;
00331   }
00332   os << endl;
00333 }
00334 
00335 
00344 bool FormationTypeInfo::setPosHome( VecPosition pos, int atIndex )
00345 {
00346   posHome[ atIndex ] = pos;
00347   return true;
00348 }
00349 
00355 bool FormationTypeInfo::setXPosHome( double x, int atIndex )
00356 {
00357   posHome[ atIndex ].setX( x );
00358   return true;
00359 }
00360 
00366 bool FormationTypeInfo::setYPosHome( double y, int atIndex )
00367 {
00368   posHome[ atIndex ].setY( y );
00369   return true;
00370 }
00371 
00377 VecPosition FormationTypeInfo::getPosHome( int atIndex ) const
00378 {
00379   return posHome[ atIndex ];
00380 }
00381 
00387 bool FormationTypeInfo::setPlayerType( PlayerT type, int atIndex )
00388 {
00389   playerType[ atIndex ] = type;
00390   return true;
00391 }
00392 
00396 PlayerT FormationTypeInfo::getPlayerType( int atIndex ) const
00397 {
00398   return playerType[ atIndex ];
00399 }
00400 
00406 bool FormationTypeInfo::setPlayerTypeInfo( PlayerTypeInfo info, int atIndex )
00407 {
00408   playerTypeInfo[ atIndex ] = info;
00409   return true;
00410 }
00411 
00416 PlayerTypeInfo* FormationTypeInfo::getPlayerTypeInfo( int atIndex )
00417 {
00418   return &playerTypeInfo[ atIndex ];
00419 }
00420 
00421 
00426 PlayerTypeInfo* FormationTypeInfo::getPlayerTypeInfoOfPlayer(
00427                                                        int iPlayerInFormation )
00428 {
00429   return &playerTypeInfo[ playerType[iPlayerInFormation] ];
00430 }
00431 
00432 /******************************************************************************/
00433 /********************** CLASS FORMATIONS **************************************/
00434 /******************************************************************************/
00435 
00443 Formations::Formations( const char *strFile, FormationT curFt, int iNr )
00444 {
00445   if( strFile == NULL )
00446   {
00447     cerr << "(Formations::Formations) No Filename given" << endl;
00448     return;
00449   }
00450 
00451   if( readFormations( strFile ) == false )
00452     cerr << "(Formations::Formations) Error reading file" << endl;
00453   curFormation = curFt;
00454   setPlayerInFormation( iNr );
00455 }
00456 
00461 void Formations::show( ostream &os )
00462 {
00463   for( int i = 0 ; i < MAX_FORMATION_TYPES; i ++ )
00464     formations[i].show( os );
00465   os << "Current formation: " << (int)curFormation << endl
00466        << "Player nr in formation: " << iPlayerInFormation ;
00467 }
00468 
00488 VecPosition Formations::getStrategicPosition( int iPlayer, VecPosition posBall,
00489                   double dMaxXInPlayMode )
00490 {
00491   VecPosition     posHome;
00492   PlayerTypeInfo* ptInfo = formations[curFormation].
00493                             getPlayerTypeInfoOfPlayer( iPlayer );
00494   double x, y;
00495 
00496   // get the home position and calculate the associated strategic position
00497   posHome = formations[curFormation].getPosHome( iPlayer );
00498   y = posHome.getY() + posBall.getY() * ptInfo->getAttrY();
00499   x = posHome.getX() + posBall.getX() * ptInfo->getAttrX();
00500 
00501   // do not move to much to the side
00502   if( fabs( y ) > 0.5*0.75*PITCH_WIDTH )
00503     y -= 0.5*posBall.getY() * ptInfo->getAttrY();
00504 
00505   // when behind ball is set, do not move to point in front of ball
00506   if( ptInfo->getBehindBall() == true && x > posBall.getX() )
00507     x = posBall.getX();
00508 
00509   // do not move past maximal x or before minimal x
00510   if( x > ptInfo->getMaxX() )
00511     x = ptInfo->getMaxX();
00512   else if( x < ptInfo->getMinX() )
00513     x = ptInfo->getMinX();
00514 
00515   // when x coordinate is in front of allowed x value, change it
00516   if( x > dMaxXInPlayMode )
00517     x = dMaxXInPlayMode;
00518 
00519   return VecPosition( x, y );
00520 }
00521 
00534 bool Formations::readFormations( const char *strFile )
00535 {
00536   ifstream in( strFile );
00537   if( !in )
00538   {
00539     cerr << "(readValues::readValues) Could not open file '" <<
00540     strFile << "'" << endl;
00541     return false;
00542   }
00543 
00544   char strLine[256], *str;
00545   int            iLineNr          = 0, i;
00546   int            iForm            = 0; // current formation type that is parsed
00547   int            iLineInFormation = 0; // current offset of line in formation
00548   bool           bReturn          = true;
00549   PlayerTypeInfo *pt_info;
00550 
00551   // read all lines
00552   while( bReturn && in.getline( strLine, sizeof(strLine) ) )
00553   {
00554     str = &strLine[0];
00555     iLineNr++;
00556     // comment and empty lines should be skipped
00557     if( !(strLine[0] == '\n' || strLine[0] == '#' || strLine[0]=='\0' ||
00558           Parse::gotoFirstNonSpace( &str ) == '\0' ) )
00559     {
00560       // there are nine different lines in a formation (see comment above)
00561       // all values for each line are parsed in one iteration
00562       // after all 9 lines are parsed, the sequence it is resetted.
00563       switch( iLineInFormation )
00564       {
00565         case 0: // first line is the number of the formation
00566           iForm = Parse::parseFirstInt( &str );
00567           break;
00568         case 1: // the x coordinate of the home pos for all the players
00569           for( i = 0 ; i < MAX_TEAMMATES ; i ++ )
00570             formations[iForm].setXPosHome(Parse::parseFirstDouble(&str), i);
00571           break;
00572         case 2: // the y coordinate of the home pos for all the players
00573           for( i = 0 ; i < MAX_TEAMMATES ; i ++ )
00574             formations[iForm].setYPosHome(Parse::parseFirstDouble(&str), i);
00575           break;
00576         case 3: // the player types for all the players
00577           for( i = 0 ; i < MAX_TEAMMATES ; i ++ )
00578             formations[iForm].setPlayerType(
00579                 (PlayerT) Parse::parseFirstInt(&str), i);
00580           break;
00581         case 4: // the x attraction for all the player types
00582           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00583           {
00584             pt_info = formations[iForm].getPlayerTypeInfo( i );
00585             pt_info->setAttrX( Parse::parseFirstDouble( &str ) );
00586           }
00587           break;
00588         case 5: // the y attraction for all the player types
00589           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00590           {
00591             pt_info = formations[iForm].getPlayerTypeInfo( i );
00592             pt_info->setAttrY( Parse::parseFirstDouble( &str ) );
00593           }
00594           break;
00595         case 6: // stay behind the ball for all the player types
00596           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00597           {
00598             pt_info = formations[iForm].getPlayerTypeInfo( i );
00599             if( Parse::parseFirstInt( &str ) == 1 )
00600               pt_info->setBehindBall( true );
00601             else
00602               pt_info->setBehindBall( false );          ;
00603           }
00604           break;
00605         case 7: // the minimal x coordinate for all the player types
00606           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00607           {
00608             pt_info = formations[iForm].getPlayerTypeInfo( i );
00609             pt_info->setMinX( Parse::parseFirstDouble( &str ));
00610           }
00611           break;
00612         case 8:// the maximal x coordinate for all the player types
00613           for( i = 0 ; i < MAX_PLAYER_TYPES ; i ++ )
00614           {
00615             pt_info = formations[iForm].getPlayerTypeInfo( i );
00616             pt_info->setMaxX( Parse::parseFirstDouble( &str ));
00617           }
00618           break;
00619         default:
00620           cerr << "(Formations::readFormations) error line " << iLineNr <<endl;
00621           return false;
00622       }
00623 
00624       iLineInFormation++;         // go one line further
00625       if( iLineInFormation == 9 ) // each formation consists of nine lines
00626         iLineInFormation = 0;
00627     }
00628   }
00629   return true;
00630 }
00631 
00635 bool Formations::setFormation( FormationT formation )
00636 {
00637   curFormation = formation;
00638   return true;
00639 }
00640 
00643 FormationT Formations::getFormation( ) const
00644 {
00645   return curFormation;
00646 }
00647 
00652 bool Formations::setPlayerInFormation( int iNumber )
00653 {
00654   iPlayerInFormation = iNumber;
00655   return true;
00656 }
00657 
00660 int Formations::getPlayerInFormation( ) const
00661 {
00662   return iPlayerInFormation;
00663 }
00664 
00667 PlayerT Formations::getPlayerType( ) const
00668 {
00669   return formations[ curFormation ].getPlayerType( iPlayerInFormation );
00670 }
00671 
00672 /*************************** TESTING PURPOSES *********************************/
00673 
00674 /*
00675 int main( void )
00676 {
00677   Formations fs( "formations.conf" );
00678   fs.show( cout );
00679 }
00680 */

Generated on Thu Mar 7 00:37:42 2002 for UvA Trilearn 2001 by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001