#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <memory>
#include <utility>

bool comp(GameObject gm_obj1, GameObject gm_obj2) {
    return gm_obj1.id > gm_obj2.id;
}
class GameDatabase {
 private:
std::map<ObjectId, std::unique_ptr<GameObject>> db;

 public:
GameDatabase() = default;
void Insert(ObjectId id, string name, size_t x, size_t y) {
if (db.find(id) == db.end()) {
auto game_obj = std::make_unique<GameObject>();
(*game_obj).id = id;
(*game_obj).name = name;
(*game_obj).x = x;
(*game_obj).y = y;
db.insert({ id, std::move(game_obj) });
} else {
db.erase(id);
}
}
void Remove(ObjectId id) {
if (db.find(id) != db.end()) {
db.erase(id);
}
}
vector<GameObject> DataByName(string name) {
vector <GameObject> names;
for (auto it = db.begin(); it != db.end(); it++) {
if (it->second->name == name) {
auto game_obj = GameObject();
game_obj.id = it->second->id;
game_obj.name = it->second->name;
game_obj.x = it->second->x;
game_obj.y = it->second->y;
names.push_back(game_obj);
}
}
std::sort(names.begin(), names.end(), comp);
return names;
}
vector<GameObject> DataByPosition(size_t x, size_t y) {
vector <GameObject> poses;
for (auto it = db.begin(); it != db.end(); it++) {
if (it->second->x == x && it->second->y == y) {
auto game_obj = GameObject();
game_obj.id = it->second->id;
game_obj.name = it->second->name;
game_obj.x = it->second->x;
game_obj.y = it->second->y;
poses.push_back(game_obj);
}
}
std::sort(poses.begin(), poses.end(), comp);
return poses;
}

vector<GameObject> Data() {
vector<GameObject> res;
for (auto it = db.begin(); it != db.end(); it++) {
auto game_obj = GameObject();
game_obj.id = it->second->id;
game_obj.name = it->second->name;
game_obj.x = it->second->x;
game_obj.y = it->second->y;
res.push_back(game_obj);
}
std::sort(res.begin(), res.end(), comp);
return res;
}
};