#pragma once #include #include #include #include struct Coordinates { size_t x; size_t y; }; bool operator<(const Coordinates& lhs, const Coordinates& rhs) { return tie(lhs.x, lhs.y) < tie(rhs.x, rhs.y); } bool operator>(const Coordinates& lhs, const Coordinates& rhs) { return tie(lhs.x, lhs.y) > tie(rhs.x, rhs.y); } bool operator==(const Coordinates& lhs, const Coordinates& rhs) { return tie(lhs.x, lhs.y) == tie(rhs.x, rhs.y); } bool operator<(const GameObject& lhs, const GameObject& rhs) { return lhs.id < rhs.id; } bool operator>(const GameObject& lhs, const GameObject& rhs) { return lhs.id > rhs.id; } bool operator==(const GameObject& lhs, const GameObject& rhs) { return lhs.id == rhs.id; } class GameDatabase { public: GameDatabase() = default; /// вставляет в базу объект с именем [name] и позицией [x, y] /// если объект с таким id в базе уже есть, заменяет его новым void Insert(ObjectId id, string name, size_t x, size_t y) { Remove(id); auto new_game_object = GameObject{id, name, x, y}; database_.insert(new_game_object); database_by_id_[id] = new_game_object; database_by_name_[name].insert(new_game_object); database_by_coordinates_[Coordinates{x, y}].insert(new_game_object); } /// удаляет элемент по id /// если такого элемента нет, ничего не делает void Remove(ObjectId id) { auto find_it = database_by_id_.find(id); if (find_it != database_by_id_.end()) { database_.erase(find_it->second); database_by_name_[find_it->second.name].erase(find_it->second); database_by_coordinates_[ Coordinates{find_it->second.x, find_it->second.y}]. erase(find_it->second); database_by_id_.erase(id); } } /// возвращает вектор объектов c именем [name] /// сортировка по убыванию id vector DataByName(string name) const { vector v; try { v = vector(database_by_name_.at(name).rbegin(), database_by_name_.at(name).rend()); } catch (out_of_range& e) {} return v; } /// возвращает вектор объектов, находящихся в позиции [x, y] /// сортировка по убыванию id vector DataByPosition(size_t x, size_t y) const { vector v; try { return vector( database_by_coordinates_.at(Coordinates{x, y}).rbegin(), database_by_coordinates_.at(Coordinates{x, y}).rend()); } catch (out_of_range& e) {} return v; } /// возвращает вектор всех объектов из базы /// сортировка по убыванию id vector Data() const { return vector(database_.rbegin(), database_.rend()); } private: set database_; map database_by_id_; map> database_by_name_; map> database_by_coordinates_; };