66TODO:
77
88- separate objects from controllers. Give controllers observed state instead of full world.
9- - hold mode: no need to press keys, if you hold them input is taken for every frame
109- redo previous human action
1110- pause
1211- use protobuf serialization for full world state, controller world view, and controller actions
2726#include < ctime>
2827#include < iostream>
2928#include < memory>
29+ #include < typeinfo>
3030#include < vector>
3131
3232const unsigned int COLOR_MAX = 255 ;
@@ -87,6 +87,18 @@ class DrawableObject {
8787 Object *object;
8888};
8989
90+ class WorldView {
91+ public:
92+ WorldView (unsigned int width, unsigned int height, std::unique_ptr<std::vector<std::unique_ptr<Object>>> objects) :
93+ width (width), height(height), objects(std::move(objects)) {}
94+ unsigned int getHeight () const { return this ->height ; }
95+ unsigned int getWidth () const { return this ->width ; }
96+ private:
97+ unsigned int width;
98+ unsigned int height;
99+ std::unique_ptr<std::vector<std::unique_ptr<Object>>> objects;
100+ };
101+
90102class World {
91103 public:
92104 World (
@@ -104,6 +116,7 @@ class World {
104116 // / Collect desired actions from all objects, and resolve them
105117 unsigned int getHeight () const ;
106118 unsigned int getNHumanActions () const ;
119+ const std::vector<std::unique_ptr<Object>>& getObjects () const ;
107120 SDL_Renderer * getRenderer () const ;
108121 unsigned int getTileWidthPix () const ;
109122 unsigned int getTileHeightPix () const ;
@@ -130,6 +143,7 @@ class World {
130143 std::vector<SDL_Texture *> textures;
131144
132145 SDL_Texture * createSolidTexture (unsigned int r, unsigned int g, unsigned int b, unsigned int a);
146+ std::unique_ptr<WorldView> createWorldView (const std::unique_ptr<Object> &object) const ;
133147};
134148
135149Object::Object (){}
@@ -198,6 +212,56 @@ class HumanPlayerObject : public Object {
198212 virtual bool takesHumanAction () const { return true ; }
199213};
200214
215+ // / Dumb: no understanding of walls.
216+ class FollowPlayerObject : public Object {
217+ public:
218+ FollowPlayerObject (unsigned int x, unsigned int y) : Object(x, y) {}
219+ virtual Action act (World *world) {
220+ Action a;
221+ for (auto const & object : world->getObjects ()) {
222+ if (typeid (*object) == typeid (HumanPlayerObject)) {
223+ if (this ->getX () < object->getX ()) {
224+ a.setDirectionX (Action::DirectionX::X_RIGHT );
225+ } else if (this ->getX () > object->getX ()) {
226+ a.setDirectionX (Action::DirectionX::X_LEFT );
227+ }
228+ if (this ->getY () < object->getY ()) {
229+ a.setDirectionY (Action::DirectionY::Y_UP );
230+ } else if (this ->getY () > object->getY ()) {
231+ a.setDirectionY (Action::DirectionY::Y_DOWN );
232+ }
233+ break ;
234+ }
235+ }
236+ return a;
237+ };
238+ };
239+
240+ // / Dumb: no understanding of walls.
241+ class FleePlayerObject : public Object {
242+ public:
243+ FleePlayerObject (unsigned int x, unsigned int y) : Object(x, y) {}
244+ virtual Action act (World *world) {
245+ Action a;
246+ for (auto const & object : world->getObjects ()) {
247+ if (typeid (*object) == typeid (HumanPlayerObject)) {
248+ if (this ->getX () < object->getX ()) {
249+ a.setDirectionX (Action::DirectionX::X_LEFT );
250+ } else {
251+ a.setDirectionX (Action::DirectionX::X_RIGHT );
252+ }
253+ if (this ->getY () < object->getY ()) {
254+ a.setDirectionY (Action::DirectionY::Y_DOWN );
255+ } else {
256+ a.setDirectionY (Action::DirectionY::Y_UP );
257+ }
258+ break ;
259+ }
260+ }
261+ return a;
262+ };
263+ };
264+
201265class SingleTextureDrawableObject : public DrawableObject {
202266 public:
203267 SingleTextureDrawableObject (Object *object, SDL_Texture *texture) :
@@ -245,6 +309,8 @@ World::World(
245309 createSolidTexture (COLOR_MAX , COLOR_MAX , 0 , 0 );
246310 createSolidTexture (COLOR_MAX , 0 , COLOR_MAX , 0 );
247311 createSolidTexture (0 , COLOR_MAX , COLOR_MAX , 0 );
312+ createSolidTexture (COLOR_MAX , COLOR_MAX , COLOR_MAX , 0 );
313+ createSolidTexture (COLOR_MAX / 2 , COLOR_MAX / 2 , COLOR_MAX / 2 , 0 );
248314 }
249315 this ->initPhysics ();
250316}
@@ -331,6 +397,24 @@ void World::initPhysics() {
331397 }
332398 this ->addObject (std::move (object));
333399 }
400+ {
401+ auto object = std::unique_ptr<Object>(new FollowPlayerObject (3 * this ->getWidth () / 4 , 3 * this ->getHeight () / 4 ));
402+ if (display) {
403+ drawableObjects.push_back (std::unique_ptr<DrawableObject>(
404+ new SingleTextureDrawableObject (object.get (), this ->textures [5 ])
405+ ));
406+ }
407+ this ->addObject (std::move (object));
408+ }
409+ {
410+ auto object = std::unique_ptr<Object>(new FleePlayerObject (this ->getWidth () / 4 , 3 * this ->getHeight () / 4 ));
411+ if (display) {
412+ drawableObjects.push_back (std::unique_ptr<DrawableObject>(
413+ new SingleTextureDrawableObject (object.get (), this ->textures [6 ])
414+ ));
415+ }
416+ this ->addObject (std::move (object));
417+ }
334418
335419}
336420
@@ -343,6 +427,8 @@ void World::resetPhysics() {
343427void World::update (const std::vector<std::unique_ptr<Action>> &humanActions) {
344428 auto humanActionsIt = humanActions.begin ();
345429 for (auto &object : this ->objects ) {
430+ auto worldView = createWorldView (object);
431+
346432 Action a;
347433 if (object->takesHumanAction ()) {
348434 a = **humanActionsIt;
@@ -381,6 +467,7 @@ void World::update(const std::vector<std::unique_ptr<Action>> &humanActions) {
381467
382468unsigned int World::getHeight () const { return this ->height ; }
383469unsigned int World::getNHumanActions () const { return this ->nHumanActions ; }
470+ const std::vector<std::unique_ptr<Object>>& World::getObjects () const { return this ->objects ; }
384471SDL_Renderer * World::getRenderer () const { return this ->renderer ; }
385472unsigned int World::getTileHeightPix () const { return this ->tileHeightPix ; }
386473unsigned int World::getTileWidthPix () const { return this ->tileWidthPix ; }
@@ -405,6 +492,12 @@ SDL_Texture * World::createSolidTexture(unsigned int r, unsigned int g, unsigned
405492 return texture;
406493}
407494
495+ // TODO.
496+ std::unique_ptr<WorldView> World::createWorldView (const std::unique_ptr<Object> &object) const {
497+ auto objects = std::unique_ptr<std::vector<std::unique_ptr<Object>>>();
498+ return std::unique_ptr<WorldView>(new WorldView (1 , 2 , std::move (objects)));
499+ }
500+
408501void printHelp () {
409502 std::cerr <<
410503 " # CLI Options\n "
0 commit comments