Perception.h

00001 // ----------------------------------------------------------------------------
00002 //
00003 // tagGame - Example code from the book:
00004 //
00005 //           Artficial Intelligence for Computer Games: An Introduction
00006 //           by John David Funge
00007 //
00008 //           www.ai4games.org
00009 //
00010 // Source code distributed under the Copyright (c) 2003-2007, John David Funge
00011 // Original author: John David Funge (www.jfunge.com)
00012 //
00013 // Licensed under the Academic Free License version 3.0 
00014 // (for details see LICENSE.txt in this directory).
00015 //
00016 // ----------------------------------------------------------------------------
00017 
00018 #ifndef TG_PERCEPTION_H
00019 #define TG_PERCEPTION_H
00020 
00021 #include "GameState.h"
00022 #include "Character.h"
00023 #include "Timer.h"
00024 #include "Circle.h"
00025 
00026 #include <map>
00027 
00028 namespace tagGame
00029 {
00032    class Perception
00033    {
00034    public:
00035       Perception(GameState* gs);
00036       ~Perception();
00037 
00043       inline void setMe(Character* me);
00044 
00050       inline void setTagged(Character* tagged);
00051 
00053       inline Character* getMe() const;
00054       inline Character* getTagged() const;
00055 
00057       inline RealVec const& myPosition() const;
00058       inline RealVec myVelocity() const;
00059       inline Real mySpeed() const;
00060       inline RealVec const& myOrientation() const;
00061       inline Real myMaxExtent() const;
00062       inline Real myExtent(RealVec const& dir) const;
00063       inline Real myMaxSpeed(void) const;
00064       inline bool myselfTagged() const;
00065 
00067       Character const* whoLastTaggedMe() const;
00068 
00070       static int const recentThreshold = 5000;
00071 
00073       int myRecentTaggedCount() const;
00074       bool myselfRecentlyTagged() const;
00075 
00077       inline RealVec const& taggedPosition() const;
00078       inline RealVec taggedVelocity() const;
00079       inline RealVec taggedRelativePosition() const;
00080       inline Real distanceSquaredToTagged() const;
00081       inline Real distanceToTagged() const;
00082 
00084       inline RealVec taggedFuturePosition() const;
00085 
00087       Character* nearestCharacter() const;
00088       inline RealVec const& nearestCharacterPosition() const;
00089       inline RealVec nearestCharacterRelativePosition() const;
00090       inline Real distanceSquaredToNearestCharacter() const;
00091       inline Real distanceToNearestCharacter() const;
00092 
00094       Obstacle* nearestObstacle() const; 
00095       inline RealVec nearestObstaclePosition() const;
00096       inline RealVec nearestObstacleRelativePosition() const;
00097       inline Real distanceSquaredToNearestObstacle() const;
00098       inline Real distanceToNearestObstacle() const;
00099 
00102       inline RealVec const& position(Obstacle const& which) const;
00103       inline RealVec relativePosition(Obstacle const& which) const;
00104       inline Real distanceSquaredTo(Obstacle const& which) const;      
00105       inline Real distanceTo(Obstacle const& which) const;
00106 
00116       Real timeToCollision() const;
00118       RealVec nextCollisionPoint() const;
00120       Obstacle* nextCollider() const;
00121 
00123       inline int getFrame();
00124       inline int getTicks();
00125       inline Real getTime();
00126 
00129       inline GameState* getGameState();
00130 
00131    private:
00132       // Update state information about who tagged who last.
00133       void updateLastTagged();
00134 
00135       // Pointer to the game-state object
00136       GameState* gs;
00137       // The character from whose point of view percepts are to be calculated.
00138       Character* me;
00139       // The tagged character.
00140       Character* tagged;
00141       // The previous tagged character.
00142       Character* lastTagged;
00143 
00144       std::map<Character*,Character*> lastTaggedByList;
00145 
00146       enum cacheType
00147       {
00148          nearestCharacterCache,
00149          nearestObstacleCache,
00150          nextColliderCache,
00151          objectCacheSize
00152       };
00153 
00154       mutable std::vector<Obstacle*> objectCache;
00155    };
00156 
00157    typedef bool (Perception::*PerceptBool)() const;
00158    typedef int (Perception::*PerceptInt)() const;
00159    typedef Real (Perception::*PerceptReal)() const;
00160 
00161    void Perception::setMe(Character* me)
00162    {
00163       TG_ASSERT(me);
00164    
00165       this->me = me;
00166    
00167       // Currently, the cache is only valid so long as the point of view
00168       // doesn't change.  That is, when a controller is selecting an
00169       // action for a single character, some values don't have to be
00170       // recomputed if they have previously already been determined.
00171       // Note that, caches could be maintained on a per character basis.
00172       // This would mean the cache could still be useful even if actions
00173       // were not computed for each character sequentially.  In addition,
00174       // caches could only be invalidated after n frames, thus avoiding
00175       // additional computation at the expense (as n increases) of less
00176       // accurate information.
00177       fill(objectCache.begin(),objectCache.end(), static_cast<Obstacle*>(NULL));
00178    }
00179    
00180    void Perception::setTagged(Character* tagged)
00181    {
00182       TG_ASSERT(tagged);
00183       TG_ASSERT(tagged->getIsTagged());
00184    
00185       lastTagged = this->tagged;
00186       this->tagged = tagged;
00187       // Assume tagged was tagged by last tagged.  The lastTaggedByList will become
00188       // corrupt if the game ever omits to call setTagged when a new character is
00189       // tagged.
00190       lastTaggedByList[tagged] = lastTagged;
00191    }
00192    
00193    Character* Perception::getMe(void) const
00194    {
00195       return me;
00196    }
00197    
00198    Character* Perception::getTagged(void) const
00199    {
00200       return tagged;
00201    }
00202    
00203    RealVec const& Perception::myPosition() const
00204    {
00205       return me->getPosition();
00206    }
00207    
00208    // TODO: add a void for all empty function argument lists
00209    RealVec Perception::myVelocity(void) const
00210    {
00211       return me->getVelocity();
00212    }
00213    
00214    Real Perception::mySpeed() const
00215    {
00216       return me->getSpeed();
00217    }
00218    
00219    RealVec const& Perception::myOrientation(void) const
00220    {
00221       return me->getOrientation();
00222    }
00223    
00224    Real Perception::myMaxExtent() const
00225    {
00226       // TODO: Use more notion of extent in the rest of the game.
00227       return static_cast<Circle const&>(me->getShape()).getRadius();
00228    }
00229    
00230    Real Perception::myExtent(RealVec const& dir) const
00231    {
00232       // Use more notion of extent in the rest of the game.
00233       return static_cast<Circle const&>(me->getShape()).getRadius();
00234    }
00235    
00236    Real Perception::myMaxSpeed(void) const
00237    {
00238       return me->getMaxSpeed();
00239    }
00240    
00241    bool Perception::myselfTagged() const
00242    {
00243       return tagged == me;
00244    }
00245    
00246    RealVec const& Perception::taggedPosition(void) const
00247    {
00248       TG_ASSERT(tagged);
00249    
00250       return tagged->getPosition();
00251    }
00252    
00253    RealVec Perception::taggedVelocity(void) const
00254    {
00255       TG_ASSERT(tagged);
00256    
00257       return tagged->getVelocity();
00258    }
00259    
00260    RealVec Perception::taggedRelativePosition(void) const
00261    {
00262       TG_ASSERT(tagged);
00263    
00264       return taggedPosition().relativeTo(myPosition());
00265    }
00266    
00267    Real Perception::distanceSquaredToTagged() const
00268    {
00269       assert(tagged);
00270    
00271       return me->distanceSquaredTo(*tagged);
00272    }
00273    
00274    Real Perception::distanceToTagged() const
00275    {
00276       TG_ASSERT(tagged);
00277    
00278       return me->distanceTo(*tagged);
00279    }
00280    
00281    RealVec Perception::taggedFuturePosition() const
00282    {
00283       RealVec p(taggedPosition());
00284       return p.add(taggedVelocity());
00285    }
00286    
00287    RealVec const& Perception::nearestCharacterPosition() const
00288    {
00289       return nearestCharacter()->getPosition();
00290    }
00291    
00292    RealVec Perception::nearestCharacterRelativePosition() const
00293    {
00294       return nearestCharacterPosition().relativeTo(myPosition());
00295    }
00296    
00297    Real Perception::distanceSquaredToNearestCharacter() const
00298    {
00299       return me->distanceSquaredTo(*nearestCharacter());
00300    }
00301    
00302    Real Perception::distanceToNearestCharacter() const
00303    {
00304       return me->distanceTo(*nearestCharacter());
00305    }
00306    
00307    RealVec const& Perception::position(Obstacle const& which) const
00308    {
00309       return which.getPosition();
00310    }
00311    
00312    RealVec Perception::relativePosition(Obstacle const& which) const
00313    {
00314       return position(which).relativeTo(myPosition());
00315    }
00316    
00317    Real Perception::distanceSquaredTo(Obstacle const& which) const
00318    {
00319       return me->distanceSquaredTo(which);
00320    }
00321    
00322    Real Perception::distanceTo(Obstacle const& which) const
00323    {
00324       return me->distanceTo(which);
00325    }
00326    
00327    RealVec Perception::nearestObstaclePosition() const
00328    {
00329       return nearestObstacle()->getPosition();
00330    }
00331    
00332    RealVec Perception::nearestObstacleRelativePosition() const
00333    {
00334       return nearestObstaclePosition().relativeTo(myPosition());
00335    }
00336    
00337    Real Perception::distanceSquaredToNearestObstacle() const
00338    {
00339       return me->distanceSquaredTo(*nearestObstacle());
00340    }
00341    
00342    Real Perception::distanceToNearestObstacle() const
00343    {
00344       return me->distanceTo(*nearestObstacle());
00345    }
00346    
00347    int Perception::getFrame()
00348    {
00349       return gs->getFrame();
00350    }
00351    
00352    int Perception::getTicks()
00353    {
00354       // characters only know about game time
00355       return Timer::theTimer().gameTicks();
00356    }
00357 
00358    Real Perception::getTime()
00359    {
00360       // characters only know about game time
00361       return Timer::theTimer().gameTime();
00362    }
00363    
00364    GameState* Perception::getGameState()
00365    {
00366       TG_ASSERT(gs);
00367    
00368       return gs;
00369    }
00370 }
00371 
00372 #endif
00373 

Generated on Sat Mar 31 22:30:54 2007 for tagGame by  doxygen 1.5.1