Last active
April 26, 2016 08:45
-
-
Save BastienClement/6baeddf95878b9e279e89507b8d98457 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* TE3 | |
* Bastien Clément | |
* 26.04.2016 | |
*/ | |
#include <iostream> | |
#include <string> | |
#include <sstream> | |
#include <vector> | |
#include <algorithm> | |
using namespace std; | |
// Missing STL operator | |
string operator+(const string& s, int i) { | |
ostringstream os; | |
os << s << i; | |
return os.str(); | |
} | |
class Location { | |
const string _name; | |
Location(const char* name) : _name(name) { } | |
Location(const Location& l) = delete; | |
void operator=(const Location& l) = delete; | |
public: | |
string name() const { return _name; } | |
static const Location Tatooine, Endor, Coruscant; | |
}; | |
const Location Location::Tatooine("Tatooine"), | |
Location::Endor("Endor"), | |
Location::Coruscant("Coruscant"); | |
bool operator==(const Location& a, const Location& b) { | |
return &a == &b; | |
} | |
/** | |
* Entity | |
*/ | |
class Entity { | |
private: | |
const string _name; | |
const Location* _location; | |
public: | |
Entity(const string& name, const Location& location) : | |
_name(name), _location(&location) { } | |
const string& name() const { | |
return _name; | |
} | |
const Location& location() const { | |
return *_location; | |
}; | |
virtual const string& speech() const = 0; | |
virtual string description() const { | |
return _name + ", location: " + _location->name() + ", speech: " + speech(); | |
} | |
virtual void move(const Location& location) { | |
cout << _name << " moves to " << location.name() << endl;; | |
_location = &location; | |
} | |
virtual void speak() const { | |
cout << _name << " says '" << speech() << "'" << endl; | |
} | |
}; | |
/** | |
* Jedi | |
*/ | |
class Jedi : public Entity { | |
// Required since speech() returns a reference | |
static const string JEDI_SPEECH; | |
public: | |
Jedi(const string& name, const Location& location) : Entity(name, location) { } | |
virtual const string& speech() const { | |
return JEDI_SPEECH; | |
} | |
}; | |
const string Jedi::JEDI_SPEECH = "May the Force be with you!"; | |
/** | |
* Droid | |
*/ | |
class Droid : public Entity { | |
static int _nextSerialNumber; | |
static vector<const Droid*> droids; | |
const int _serialNumber; | |
const string _noise; | |
const Jedi* _owner; | |
public: | |
Droid(const string& name, const string& noise, const Jedi& owner) : | |
Entity(name + _nextSerialNumber, owner.location()), | |
_serialNumber(_nextSerialNumber++), _noise(noise), _owner(&owner) { | |
droids.push_back(this); | |
} | |
virtual const string& speech() const { | |
return _noise; | |
} | |
// Override description() to add owner information | |
virtual string description() const { | |
return Entity::description() + ", owner: " + _owner->name(); | |
} | |
// Override move() to handle the "droid has found its master" case | |
virtual void move(const Location& location) { | |
Entity::move(location); | |
if (location == _owner->location()) { | |
cout << name() << " has found its master " << _owner->name() << "!" << endl; | |
speak(); | |
} | |
} | |
static void printDroids() { | |
for_each(droids.begin(), droids.end(), [](const Droid* droid) { | |
cout << droid->description() << endl; | |
}); | |
} | |
}; | |
int Droid::_nextSerialNumber = 1; | |
vector<const Droid*> Droid::droids = vector<const Droid*>(); | |
int main() { | |
cout << "-- Luke & R1" << endl; | |
Jedi luke("Luke", Location::Tatooine); | |
Droid r1("R", "Doo-bi-boop", luke); | |
cout << luke.description() << endl; | |
cout << r1.description() << endl; | |
luke.move(Location::Endor); | |
r1.move(Location::Coruscant); | |
r1.move(Location::Endor); | |
luke.speak(); | |
Droid r2("R", "Bziooop", luke); | |
cout << endl << "-- Existing droids" << endl; | |
Droid::printDroids(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment