#include <unordered_map>
#include <algorithm>
#include <string>
#include <vector>
class GameDatabase {
 private:
    std::unordered_map<ObjectId, GameObject> map;

 public:
    GameDatabase() = default;

    /// вставляет в базу объект с именем [name] и позицией [x, y]
    /// если объект с таким id в базе уже есть, заменяет его новым
    void Insert(ObjectId id, string name, size_t x, size_t y) {
        map[id] = GameObject{ id, name, x, y };
    }

    /// удаляет элемент по id
    /// если такого элемента нет, ничего не делает
    void Remove(ObjectId id) {
        map.erase(id);
    }
    struct less_than_id {
        inline bool operator() (const GameObject& obj1,
            const GameObject& obj2) {
             return (obj1.id > obj2.id);
        }
    };
    vector<GameObject> DataByName(string name) const {
        std::vector<GameObject> vals;
        vals.reserve(map.size());

        for (auto kv : map) {
            if (kv.second.name == name) {
                vals.push_back(kv.second);
            }
        }
        std::sort(vals.begin(), vals.end(), less_than_id());
        return vals;
    }

    /// возвращает вектор объектов, находящихся в позиции [x, y]
    /// сортировка по убыванию id
    vector<GameObject> DataByPosition(size_t x, size_t y) const {
        std::vector<GameObject> vals;
        vals.reserve(map.size());

        for (auto kv : map) {
            if (kv.second.x == x && kv.second.y == y) {
                vals.push_back(kv.second);
            }
        }
        std::sort(vals.begin(), vals.end(), less_than_id());
        return vals;
    }

    /// возвращает вектор всех объектов из базы
    /// сортировка по убыванию id
    vector<GameObject> Data() const {
        std::vector<GameObject> vals;
        vals.reserve(map.size());

        for (auto kv : map) {
            vals.push_back(kv.second);
        }
        std::sort(vals.begin(), vals.end(), less_than_id());
        return vals;
    }
};