src/tron/gAIBase.h

Go to the documentation of this file.
00001 /*
00002 
00003 *************************************************************************
00004 
00005 ArmageTron -- Just another Tron Lightcycle Game in 3D.
00006 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
00007 
00008 **************************************************************************
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00023   
00024 ***************************************************************************
00025 
00026 */
00027 
00028 #ifndef ArmageTron_AIBASE_H
00029 #define ArmageTron_AIBASE_H
00030 
00031 #include "rSDL.h"
00032 
00033 #include "eTimer.h"
00034 #include "ePath.h"
00035 #include "ePlayer.h"
00036 #include "eTeam.h"
00037 #include "gCycle.h"
00038 #include "tList.h"
00039 #include "tRandom.h"
00040 #include "nObserver.h"
00041 
00042 class gSensor;
00043 class gAISensor;
00044 class gAILog;
00045 class gAICharacter;
00046 
00047 typedef enum
00048 { AI_SURVIVE = 0,   // just try to stay alive
00049   AI_TRACE,         // trace a wall
00050   AI_PATH,          // follow a path to a target
00051   AI_CLOSECOMBAT    // try to frag a nearby opponent
00052 }
00053 gAI_STATE;
00054 
00055 class gSimpleAI
00056 {
00057 public:
00058     gSimpleAI()
00059     {
00060     }
00061 
00062     // do the thinking
00063     inline REAL Think()
00064     {
00065         return DoThink();
00066     }
00067 
00068     virtual ~gSimpleAI();
00069 
00070     gCycle * Object(){ return object_; }
00071     void SetObject( gCycle * cycle ){ object_ = cycle; }
00072 protected:
00073     virtual REAL DoThink() = 0;
00074 private:
00075     tJUST_CONTROLLED_PTR< gCycle > object_;
00076 };
00077 
00078 class gSimpleAIFactory: public tListItem< gSimpleAIFactory >
00079 {
00080 public:
00081     gSimpleAI * Create( gCycle * object ) const;
00082     static gSimpleAIFactory * Get();
00083     static void Set( gSimpleAIFactory * factory );
00084 protected:
00085     virtual gSimpleAI * DoCreate() const = 0;
00086 private:
00087     static gSimpleAIFactory *factory_;
00088 };
00089 
00090 class gAIPlayer: public ePlayerNetID{
00091     friend class gAITeam;
00092 
00093     tReproducibleRandomizer randomizer_;
00094 protected:
00095     gSimpleAI *simpleAI_;
00096     gAICharacter*           character; // our specification of abilities
00097 
00098     // for all offensive modes:
00099     nObserverPtr< gCycle >    target;  // the current victim
00100 
00101     // for pathfinding mode:
00102     ePath                   path;    // last found path to the victim
00103     REAL lastPath;                   // when was the last time we did a pathsearch?
00104 
00105     // for trace mode:
00106     int  traceSide;
00107     REAL lastChangeAttempt;
00108     REAL lazySideChange;
00109 
00110     // state management:
00111     gAI_STATE state;             // the current mode of operation
00112     REAL      nextStateChange;   // when is the operation mode allowed to change?
00113 
00114     bool emergency;              // tell if an emergency is present
00115     int  triesLeft;              // number of tries left before we die
00116 
00117     REAL freeSide;               // number that tells which side is probably free for evasive actions
00118 
00119     // basic thinking:
00120     REAL lastTime;
00121     REAL nextTime;
00122 
00123     REAL concentration;
00124 
00125     // log
00126     gAILog* log;
00127 
00128     //  gCycle * Cycle(){return object;}
00129 
00130     // set trace side:
00131     void SetTraceSide(int side);
00132 
00133     // state change:
00134     void SwitchToState(gAI_STATE nextState, REAL minTime=10);
00135 
00136     // data structure common to thinking functions
00137 public:
00138     struct ThinkDataBase
00139     {
00140         int turn;                                   // direction to turn to
00141         REAL thinkAgain;                            // when to think again
00142 
00143         ThinkDataBase()
00144                 : turn(0), thinkAgain(0)
00145         {
00146         }
00147     };
00148 
00149 protected:
00150 struct ThinkData : public ThinkDataBase
00151     {
00152         gAISensor const & front;                    // sensors cast by upper level function
00153         gAISensor const & left;
00154         gAISensor const & right;
00155 
00156         ThinkData( gAISensor const & a_front, gAISensor const & a_left, gAISensor const & a_right )
00157                 : front(a_front), left( a_left ), right( a_right )
00158         {
00159         }
00160     };
00161 
00162     // state update functions:
00163     virtual void ThinkSurvive( ThinkData & data );
00164     virtual void ThinkTrace( ThinkData & data );
00165     virtual void ThinkPath( ThinkData & data );
00166     virtual void ThinkCloseCombat( ThinkData & data );
00167 
00168     // emergency functions:
00169     virtual bool EmergencySurvive( ThinkData & data, int enemyEvade = -1, int preferedSide = 0);
00170     virtual void EmergencyTrace( ThinkData & data );
00171     virtual void EmergencyPath( ThinkData & data );
00172     virtual void EmergencyCloseCombat( ThinkData & data );
00173 
00174     // acting on gathered data
00175     virtual void ActOnData( ThinkData & data );
00176     virtual void ActOnData( ThinkDataBase & data );
00177 public:
00178     gAICharacter* Character() const {return character;}
00179 
00180     //  virtual void AddRef();
00181     //  virtual void Release();
00182 
00183     gAIPlayer();
00184     ~gAIPlayer();
00185 
00186     static void ClearAll(); 
00187 
00188     // called whenever cylce a drives close to the wall of cylce b.
00189     // directions: aDir tells whether the wall is to the left (-1) or right(1)
00190     // of a
00191     // bDir tells the direction the wall of b is going (-1: to the left, 1:...)
00192     // bDist is the distance of b's wall to its start.
00193     static void CycleBlocksWay(const gCycleMovement *a, const gCycleMovement *b,
00194                                int aDir, int bDir, REAL bDist, int winding);
00195 
00196     // called whenever a cylce blocks the rim wall.
00197     static void CycleBlocksRim(const gCycleMovement *a, int aDir);
00198 
00199     // called whenever a hole is ripped in a's wall at distance aDist.
00200     static void BreakWall(const gCycleMovement *a, REAL aDist);
00201 
00202     static void ConfigureAIs();  // ai configuration menu
00203 
00204     static void SetNumberOfAIs(int num, int minPlayers, int iq, int tries=3); // make sure this many AI players are in the game (with approximately the given IQ)
00205 
00206     void ClearTarget(){target=NULL;}
00207 
00208     virtual void ControlObject(eNetGameObject *c){ ePlayerNetID::ControlObject( c ); simpleAI_ = NULL; }
00209     virtual void ClearObject(){ ePlayerNetID::ClearObject(); simpleAI_ = NULL; }
00210 
00211     // do some thinking. Return value: time to think again
00212     virtual REAL Think();
00213 
00214     bool Alive(){
00215         return bool(Object()) && Object()->Alive();
00216     }
00217 
00218     virtual bool IsHuman() const { return false; }
00219 
00220     gCycle* Object()
00221     {
00222         eGameObject* go = ePlayerNetID::Object();
00223         if ( !go )
00224         {
00225             return NULL;
00226         }
00227         else
00228         {
00229             tASSERT(dynamic_cast<gCycle*>(go));
00230             return static_cast<gCycle*>(go);
00231         }
00232     }
00233 
00234     void Timestep(REAL time);
00235 
00236     virtual void NewObject();                     // called when we control a new object
00237     virtual void RightBeforeDeath(int triesLeft); // is called right before the vehicle gets destroyed.
00238 
00239     virtual void Color( REAL&r, REAL&g, REAL&b ) const;
00240 
00241     virtual nDescriptor&        CreatorDescriptor() const;
00242     gAIPlayer(nMessage &m);
00243 };
00244 
00245 // the AI team
00246 class gAITeam: public eTeam
00247 {
00248 public:
00249     gAITeam(nMessage &m);
00250     gAITeam();
00251     virtual nDescriptor &CreatorDescriptor() const;
00252 
00253     static void BalanceWithAIs(bool doBalance = balanceWithAIs);        // fill empty team positions with AI players
00254     virtual bool PlayerMayJoin(const ePlayerNetID* player) const;       // may player join this team?
00255 
00256     virtual bool BalanceThisTeam() const { return false; } // care about this team when balancing teams
00257     virtual bool IsHuman() const { return false; } // does this team consist of humans?
00258 };
00259 
00260 
00261 #endif

Generated on Sat Mar 15 22:56:05 2008 for Armagetron Advanced by  doxygen 1.5.4