#include "manage_hiscore_table.h" #include // Para SDL_GetError #include // Para SDL_RWread, SDL_RWwrite, SDL_RWFromFile #include // Para sort #include // Para basic_ostream, operator<<, cout, endl #include "utils.h" // Para HiScoreEntry, getFileName // Resetea la tabla a los valores por defecto void ManageHiScoreTable::clear() { // Limpia la tabla table_.clear(); // Añade 10 entradas predefinidas table_.push_back(HiScoreEntry("BRY", 1000000)); table_.push_back(HiScoreEntry("USUFON", 500000)); table_.push_back(HiScoreEntry("GLUCAS", 100000)); table_.push_back(HiScoreEntry("PDLGAT", 50000)); table_.push_back(HiScoreEntry("PARRAB", 10000)); table_.push_back(HiScoreEntry("PELECH", 5000)); table_.push_back(HiScoreEntry("SAHUQU", 1000)); table_.push_back(HiScoreEntry("BACTER", 500)); table_.push_back(HiScoreEntry("PEPE", 200)); table_.push_back(HiScoreEntry("ROSITA", 100)); sort(); } // Añade un elemento a la tabla int ManageHiScoreTable::add(const HiScoreEntry &entry) { // Añade la entrada a la tabla table_.push_back(entry); // Ordena la tabla sort(); // Encontrar la posición del nuevo elemento auto it = std::find_if(table_.begin(), table_.end(), [&](const HiScoreEntry &e) { return e.name == entry.name && e.score == entry.score && e.one_credit_complete == entry.one_credit_complete; }); int position = -1; if (it != table_.end()) { position = std::distance(table_.begin(), it); } // Deja solo las 10 primeras entradas if (table_.size() > 10) { table_.resize(10); // Si el nuevo elemento quedó fuera del top 10 if (position >= 10) { position = -1; // No entró en el top 10 } } // Devuelve la posición return position; } // Ordena la tabla void ManageHiScoreTable::sort() { struct { bool operator()(const HiScoreEntry &a, const HiScoreEntry &b) const { return a.score > b.score; } } scoreDescendingComparator; std::sort(table_.begin(), table_.end(), scoreDescendingComparator); } // Carga la tabla desde un fichero bool ManageHiScoreTable::loadFromFile(const std::string &file_path) { clear(); auto success = true; auto file = SDL_RWFromFile(file_path.c_str(), "rb"); if (file) { table_.clear(); // Limpia la tabla actual // Lee el número de entradas en la tabla int tableSize = 0; SDL_RWread(file, &tableSize, sizeof(int), 1); // Lee los datos de cada entrada for (int i = 0; i < tableSize; ++i) { HiScoreEntry entry; // Lee la puntuación SDL_RWread(file, &entry.score, sizeof(int), 1); // Lee el tamaño del nombre y luego el nombre int nameSize = 0; SDL_RWread(file, &nameSize, sizeof(int), 1); std::vector nameBuffer(nameSize + 1); SDL_RWread(file, nameBuffer.data(), nameSize, 1); nameBuffer[nameSize] = '\0'; // Asegurar el fin de la cadena entry.name = std::string(nameBuffer.data()); // Lee el valor de one_credit_complete int occValue = 0; SDL_RWread(file, &occValue, sizeof(int), 1); entry.one_credit_complete = (occValue != 0); // Añade la entrada a la tabla table_.push_back(entry); } std::cout << "Reading file: " << getFileName(file_path) << std::endl; SDL_RWclose(file); } else { std::cout << "Error: Unable to load " << getFileName(file_path) << " file! " << SDL_GetError() << std::endl; success = false; } return success; } // Guarda la tabla en un fichero bool ManageHiScoreTable::saveToFile(const std::string &file_path) { auto success = true; auto file = SDL_RWFromFile(file_path.c_str(), "w+b"); if (file) { // Guarda el número de entradas en la tabla int tableSize = static_cast(table_.size()); SDL_RWwrite(file, &tableSize, sizeof(int), 1); // Guarda los datos de cada entrada for (int i = 0; i < tableSize; ++i) { const HiScoreEntry& entry = table_.at(i); // Guarda la puntuación SDL_RWwrite(file, &entry.score, sizeof(int), 1); // Guarda el tamaño del nombre y luego el nombre int nameSize = static_cast(entry.name.size()); SDL_RWwrite(file, &nameSize, sizeof(int), 1); SDL_RWwrite(file, entry.name.c_str(), nameSize, 1); // Guarda el valor de one_credit_complete como un entero (0 o 1) int occValue = entry.one_credit_complete ? 1 : 0; SDL_RWwrite(file, &occValue, sizeof(int), 1); } std::cout << "Writing file: " << getFileName(file_path) << std::endl; SDL_RWclose(file); } else { std::cout << "Error: Unable to save " << getFileName(file_path) << " file! " << SDL_GetError() << std::endl; success = false; } return success; }