#include "Genome.hpp"
#include "Goal.hpp"
+#include "Memory.hpp"
#include "Need.hpp"
#include "Situation.hpp"
#include "Steering.hpp"
void Remove() noexcept { removable = true; }
bool Removable() const noexcept { return removable; }
+ Memory &GetMemory() noexcept { return memory; }
+ const Memory &GetMemory() const noexcept { return memory; }
+
void AddNeed(std::unique_ptr<Need> &&n) { needs.emplace_back(std::move(n)); }
const std::vector<std::unique_ptr<Need>> &Needs() const noexcept { return needs; }
Callback on_death;
bool removable;
+ Memory memory;
+
std::vector<std::unique_ptr<Need>> needs;
std::vector<std::unique_ptr<Goal>> goals;
--- /dev/null
+#ifndef BLOBS_CREATURE_MEMORY_HPP_
+#define BLOBS_CREATURE_MEMORY_HPP_
+
+#include "../math/glm.hpp"
+
+#include <map>
+
+
+namespace blobs {
+namespace world {
+ class Planet;
+}
+namespace creature {
+
+class Creature;
+
+class Memory {
+
+public:
+ struct Location {
+ world::Planet *planet;
+ int surface;
+ glm::ivec2 coords;
+ };
+
+public:
+ explicit Memory(Creature &);
+ ~Memory();
+
+public:
+ void Tick(double dt);
+
+private:
+ /// track time spent on a tile
+ void TrackStay(const Location &, double t);
+
+private:
+ Creature &c;
+
+ struct Stay {
+ double first_been;
+ Location first_loc;
+ double last_been;
+ Location last_loc;
+ double time_spent;
+ };
+ std::map<int, Stay> known_types;
+
+};
+
+}
+}
+
+#endif
#include "Creature.hpp"
#include "Genome.hpp"
+#include "Memory.hpp"
#include "Situation.hpp"
#include "Steering.hpp"
, health(1.0)
, on_death()
, removable(false)
+, memory(*this)
, needs()
, goals()
, situation()
<< name << " died of old age" << std::endl;
}
+ memory.Tick(dt);
for (auto &need : needs) {
need->Tick(dt);
}
}
+Memory::Memory(Creature &c)
+: c(c) {
+}
+
+Memory::~Memory() {
+}
+
+void Memory::Tick(double dt) {
+ Situation &s = c.GetSituation();
+ if (s.OnSurface()) {
+ TrackStay({ &s.GetPlanet(), s.Surface(), s.SurfacePosition() }, dt);
+ }
+}
+
+void Memory::TrackStay(const Location &l, double t) {
+ const world::TileType &type = l.planet->TypeAt(l.surface, l.coords.x, l.coords.y);
+ auto entry = known_types.find(type.id);
+ if (entry != known_types.end()) {
+ entry->second.last_been = c.GetSimulation().Time();
+ entry->second.last_loc = l;
+ entry->second.time_spent += t;
+ } else {
+ known_types.emplace(type.id, Stay{
+ c.GetSimulation().Time(),
+ l,
+ c.GetSimulation().Time(),
+ l,
+ t
+ });
+ }
+}
+
+
Situation::Situation()
: planet(nullptr)
, position(0.0)