#include <windows.h>
#include <tchar.h>
#include <map>
#include <string>
#include <iostream>
using namespace std;
class GameObject
{
public:
virtual void Collide(GameObject& otherObject) = 0;
virtual ~GameObject() {};
};
class SpaceShip: public GameObject
{
private:
typedef void (SpaceShip::*HitFunctionPtr) (GameObject&);
typedef map< std::string, HitFunctionPtr > HitMap;
public:
virtual void Collide (GameObject& otherObject);
virtual void HitSpaceShip (GameObject& spaceShip);
virtual void HitSpaceStation (GameObject& spaceStation);
virtual void HitAsteriod (GameObject& asteroid);
private:
static HitFunctionPtr Lookup (const GameObject& whatWeHit);
static HitMap* InitializeCollisionMap ();
};
class SpaceStation: public GameObject
{
private:
typedef void (SpaceStation::*HitFunctionPtr) (GameObject&);
typedef map<std::string, HitFunctionPtr> HitMap;
public:
virtual void Collide (GameObject& otherObject);
virtual void HitSpaceShip (GameObject& spaceShip);
virtual void HitSpaceStation (GameObject& spaceStation);
virtual void HitAsteriod (GameObject& asteroid);
private:
static HitFunctionPtr Lookup (const GameObject& whatWeHit);
static HitMap* InitializeCollisionMap ();
};
class Asteroid: public GameObject
{
private:
typedef void (Asteroid::*HitFunctionPtr) (GameObject&);
typedef map<std::string, HitFunctionPtr> HitMap;
public:
virtual void Collide (GameObject& otherObject);
virtual void HitSpaceShip (GameObject& spaceShip);
virtual void HitSpaceStation (GameObject& spaceStation);
virtual void HitAsteriod (GameObject& asteroid);
private:
static HitFunctionPtr Lookup (const GameObject& whatWeHit);
static HitMap* InitializeCollisionMap ();
};
SpaceShip::HitMap* SpaceShip::InitializeCollisionMap ()
{
HitMap* phm = new HitMap;
(*phm) ["class SpaceShip"] = &HitSpaceShip;
(*phm) ["class SpaceStation"] = &HitSpaceStation;
(*phm) ["class Asteroid"] = &HitAsteriod;
return phm;
}
SpaceShip::HitFunctionPtr
SpaceShip::Lookup (const GameObject& whatWeHit)
{
static auto_ptr<HitMap> collisionMap (InitializeCollisionMap () );
HitMap::iterator mapEntry = collisionMap->find ( string (typeid (whatWeHit).name ()) );
if (mapEntry == collisionMap->end () ) return 0;
return (*mapEntry).second;
}
void SpaceShip::Collide (GameObject& otherObject)
{
HitFunctionPtr hfp = Lookup (otherObject);
if (hfp)
{
(this->*hfp)(otherObject);
}
else
{
cout << "Unknown object type" << endl;
}
}
void SpaceShip::HitSpaceShip (GameObject& spaceShip)
{
SpaceShip& ship = dynamic_cast<SpaceShip&> (spaceShip);
cout << "The space ship is colliding with a space ship";
cout << endl;
}
void SpaceShip::HitSpaceStation (GameObject& spaceStation)
{
SpaceStation& station = dynamic_cast<SpaceStation&> (spaceStation);
cout << "The space ship is colliding with a space station";
cout << endl;
}
void SpaceShip::HitAsteriod (GameObject& obj)
{
Asteroid& asteroid = dynamic_cast<Asteroid&> (obj);
cout << "The space ship is colliding with a asteroid";
cout << endl;
}
SpaceStation::HitMap* SpaceStation::InitializeCollisionMap ()
{
HitMap* phm = new HitMap;
(*phm) ["class SpaceShip" ] = &HitSpaceShip;
(*phm) ["class SpaceStation"] = &HitSpaceStation;
(*phm) ["class Asteroid" ] = &HitAsteriod;
return phm;
}
SpaceStation::HitFunctionPtr
SpaceStation::Lookup (const GameObject& whatWeHit)
{
static auto_ptr<HitMap> collisionMap (InitializeCollisionMap () );
HitMap::iterator mapEntry = collisionMap->find ( string(typeid (whatWeHit).name ()) );
if (mapEntry == collisionMap->end () ) return 0;
return (*mapEntry).second;
}
void SpaceStation::Collide (GameObject& otherObject)
{
HitFunctionPtr hfp = Lookup (otherObject);
if (hfp)
{
(this->*hfp)(otherObject);
}
else
{
cout << "Unknown object type" << endl;
}
}
void SpaceStation::HitSpaceShip (GameObject& spaceShip)
{
SpaceShip& ship = dynamic_cast<SpaceShip&> (spaceShip);
cout << "The space ship is colliding with a space ship";
cout << endl;
}
void SpaceStation::HitSpaceStation (GameObject& spaceStation)
{
SpaceStation& station = dynamic_cast<SpaceStation&> (spaceStation);
cout << "The space ship is colliding with a space station";
cout << endl;
}
void SpaceStation::HitAsteriod (GameObject& obj)
{
Asteroid& asteroid = dynamic_cast<Asteroid&> (obj);
cout << "The space ship is colliding with a asteroid";
cout << endl;
}
Asteroid::HitMap* Asteroid::InitializeCollisionMap ()
{
HitMap* phm = new HitMap;
(*phm) ["class SpaceShip" ] = &HitSpaceShip;
(*phm) ["class SpaceStation"] = &HitSpaceStation;
(*phm) ["class Asteroid" ] = &HitAsteriod;
return phm;
}
Asteroid::HitFunctionPtr
Asteroid::Lookup (const GameObject& whatWeHit)
{
static auto_ptr<HitMap> collisionMap (InitializeCollisionMap () );
HitMap::iterator mapEntry = collisionMap->find ( string(typeid (whatWeHit).name ()) );
if (mapEntry == collisionMap->end () ) return 0;
return (*mapEntry).second;
}
void Asteroid::Collide (GameObject& otherObject)
{
HitFunctionPtr hfp = Lookup (otherObject);
if (hfp)
{
(this->*hfp)(otherObject);
}
else
{
cout << "Unknown object type" << endl;
}
}
void Asteroid::HitSpaceShip (GameObject& spaceShip)
{
SpaceShip& ship = dynamic_cast<SpaceShip&> (spaceShip);
cout << "The space ship is colliding with a space ship";
cout << endl;
}
void Asteroid::HitSpaceStation (GameObject& spaceStation)
{
SpaceStation& station = dynamic_cast<SpaceStation&> (spaceStation);
cout << "The space ship is colliding with a space station";
cout << endl;
}
void Asteroid::HitAsteriod (GameObject& obj)
{
Asteroid& asteroid = dynamic_cast<Asteroid&> (obj);
cout << "The space ship is colliding with a asteroid";
cout << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
SpaceShip ship;
SpaceStation station;
Asteroid asteroid;
ship.Collide(station);
ship.Collide(asteroid);
ship.Collide(ship);
ship.Collide(asteroid);
return 0;
}
--------------------------------------------------------------------------
The space ship is colliding with a space station
The space ship is colliding with a asteroid
The space ship is colliding with a space ship
The space ship is colliding with a asteroid