#include <cstdlib>
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <unordered_map>
#include <functional>
#include <string>

using std::string;

bool operator>(const GameObject &a, const GameObject &b);

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) {
        GameObject game_obj = {id, name, x, y};
        database_id[id] = game_obj;
    }

    void Remove(ObjectId id) {
        if (database_id.count(id) > 0) {
            database_id.erase(id);
        }
    }

    vector<GameObject> DataByName(string name) const {
        vector<GameObject> game_objects;
        for (const auto &item : database_id) {
            if (item.second.name == name) {
                game_objects.push_back(item.second);
            }
        }
        return game_objects;
    }

    vector<GameObject> DataByPosition(size_t x, size_t y) const {
        vector<GameObject> game_objects;
        for (const auto &item : database_id) {
            if (item.second.x == x && item.second.y == y) {
                game_objects.push_back(item.second);
            }
        }
        return game_objects;
    }

    vector<GameObject> Data() const {
        vector<GameObject> game_objects;
        for (const auto &item : database_id) {
            game_objects.push_back(item.second);
        }
        return game_objects;
    }


 private:
    map<ObjectId, GameObject, std::greater<ObjectId>> database_id;
};