00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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,
00049 AI_TRACE,
00050 AI_PATH,
00051 AI_CLOSECOMBAT
00052 }
00053 gAI_STATE;
00054
00055 class gSimpleAI
00056 {
00057 public:
00058 gSimpleAI()
00059 {
00060 }
00061
00062
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;
00097
00098
00099 nObserverPtr< gCycle > target;
00100
00101
00102 ePath path;
00103 REAL lastPath;
00104
00105
00106 int traceSide;
00107 REAL lastChangeAttempt;
00108 REAL lazySideChange;
00109
00110
00111 gAI_STATE state;
00112 REAL nextStateChange;
00113
00114 bool emergency;
00115 int triesLeft;
00116
00117 REAL freeSide;
00118
00119
00120 REAL lastTime;
00121 REAL nextTime;
00122
00123 REAL concentration;
00124
00125
00126 gAILog* log;
00127
00128
00129
00130
00131 void SetTraceSide(int side);
00132
00133
00134 void SwitchToState(gAI_STATE nextState, REAL minTime=10);
00135
00136
00137 public:
00138 struct ThinkDataBase
00139 {
00140 int turn;
00141 REAL thinkAgain;
00142
00143 ThinkDataBase()
00144 : turn(0), thinkAgain(0)
00145 {
00146 }
00147 };
00148
00149 protected:
00150 struct ThinkData : public ThinkDataBase
00151 {
00152 gAISensor const & front;
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
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
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
00175 virtual void ActOnData( ThinkData & data );
00176 virtual void ActOnData( ThinkDataBase & data );
00177 public:
00178 gAICharacter* Character() const {return character;}
00179
00180
00181
00182
00183 gAIPlayer();
00184 ~gAIPlayer();
00185
00186 static void ClearAll();
00187
00188
00189
00190
00191
00192
00193 static void CycleBlocksWay(const gCycleMovement *a, const gCycleMovement *b,
00194 int aDir, int bDir, REAL bDist, int winding);
00195
00196
00197 static void CycleBlocksRim(const gCycleMovement *a, int aDir);
00198
00199
00200 static void BreakWall(const gCycleMovement *a, REAL aDist);
00201
00202 static void ConfigureAIs();
00203
00204 static void SetNumberOfAIs(int num, int minPlayers, int iq, int tries=3);
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
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();
00237 virtual void RightBeforeDeath(int triesLeft);
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
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);
00254 virtual bool PlayerMayJoin(const ePlayerNetID* player) const;
00255
00256 virtual bool BalanceThisTeam() const { return false; }
00257 virtual bool IsHuman() const { return false; }
00258 };
00259
00260
00261 #endif