#include <string>
#include <vector>
#include <map>
#include <set>
bool operator>(const GameObject &a, const GameObject &b) {
return a.id > b.id;
}
bool operator<(const GameObject &a, const GameObject &b) {
return a.id < b.id;
}
class GameDatabase {
public:
GameDatabase() = default;
void Insert(ObjectId id, const std::string &name, size_t x, size_t y) {
GameObject tmp;
tmp.id = id;
tmp.name = name;
tmp.x = x;
tmp.y = y;
if (this->id_objects_.find(id) != this->id_objects_.end()) {
this->Remove(id);
}
this->id_objects_[id] = tmp;
this->pos_objects_[std::make_pair(x, y)].insert(id);
this->str_objects_[name].insert(id);
}
void Remove(ObjectId id) {
auto it = this->id_objects_.find(id);
if (it != this->id_objects_.end()) {
GameObject tmp = this->id_objects_[id];
this->str_objects_[tmp.name].erase(id);
this->pos_objects_[std::make_pair(tmp.x, tmp.y)].erase(id);
this->id_objects_.erase(it);
}
}
[[nodiscard]] std::pair<GameObject, bool> DataById(ObjectId id) const {
auto tmp = this->id_objects_.find(id);
return std::make_pair(tmp->second, tmp != this->id_objects_.end());
}
[[nodiscard]] std::vector<GameObject>
DataByName(const std::string& name) const {
auto tmp = this->str_objects_.find(name);
std::vector<GameObject> result;
if (tmp != this->str_objects_.end()) {
for (auto it : tmp->second)
result.push_back(DataById(it).first);
}
return result;
}
[[nodiscard]] std::vector<GameObject>
DataByPosition(size_t x, size_t y) const {
auto tmp = this->pos_objects_.find(std::make_pair(x, y));
std::vector<GameObject> result;
if (tmp != this->pos_objects_.end()) {
for (auto it : tmp->second)
result.push_back(DataById(it).first);
}
return result;
}
[[nodiscard]] std::vector<GameObject> Data() const {
std::vector<GameObject> result;
for (const auto &it : this->id_objects_) {
result.push_back(it.second);
}
return result;
}
private:
std::map<
ObjectId,
GameObject,
std::greater<>
> id_objects_;
std::map<
std::pair<size_t, size_t>,
std::set<ObjectId, std::greater<>>
> pos_objects_;
std::map<
std::string,
std::set<ObjectId, std::greater<>>
> str_objects_;
};