#include <map>
#include <utility>
#include <functional>
#include <string>
#include <vector>

bool operator> (const GameObject& a, const GameObject& b) {
    return a.id > b.id;
}

template<class Tp, template<class> class Compare>
class DereferenceCompare {
      Compare<Tp> comp;

 public:
    bool operator()(const Tp* const a, const Tp* const b) const {
        return comp(*a, *b);
    }
};

class GameDatabase {
 public:
    GameDatabase() = default;
    void Insert(ObjectId id, string name, size_t x, size_t y);
    void Remove(ObjectId id);
    vector<GameObject> DataByName(string name) const;
    vector<GameObject> DataByPosition(size_t x, size_t y) const;
    vector<GameObject> Data() const;
 private:
    map<ObjectId, GameObject, greater<ObjectId>> m;
};

void GameDatabase::Insert(ObjectId id, string name, size_t x, size_t y) {
  m[id] = {id, name, x, y};
}

void GameDatabase::Remove(ObjectId id) {
  m.erase(id);
}

vector<GameObject> GameDatabase::DataByName(string name) const {
  vector<GameObject> v;
  for (auto i : m) {
    if (i.second.name == name) {
      v.push_back(i.second);
    }
  }
  return v;
}

vector<GameObject> GameDatabase::DataByPosition(size_t x, size_t y) const {
  vector<GameObject> v;
  for (auto i : m) {
    if (i.second.x == x && i.second.y == y) {
      v.push_back(i.second);
    }
  }
  return v;
}

vector<GameObject> GameDatabase::Data() const {
  vector<GameObject> v;
  for (auto i : m) {
    v.push_back(i.second);
  }
  return v;
}