Skip to content

Instantly share code, notes, and snippets.

@BastienClement
Last active April 26, 2016 08:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BastienClement/6baeddf95878b9e279e89507b8d98457 to your computer and use it in GitHub Desktop.
Save BastienClement/6baeddf95878b9e279e89507b8d98457 to your computer and use it in GitHub Desktop.
/**
* 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