#include "manage_hiscore_table.hpp" #include // Para SDL_ReadIO, SDL_WriteIO, SDL_CloseIO, SDL_GetError, SDL_IOFromFile, SDL_LogCategory, SDL_LogError, SDL_LogInfo #include // Para find_if, sort #include // Para distance #include "utils.hpp" // Para getFileName #include "ui/logger.hpp" // Resetea la tabla a los valores por defecto void ManageHiScoreTable::clear() { // Limpia la tabla table_.clear(); // Añade 10 entradas predefinidas table_.emplace_back("BRY", 1000000); table_.emplace_back("USUFO", 500000); table_.emplace_back("GLUCA", 100000); table_.emplace_back("PARRA", 50000); table_.emplace_back("CAGAM", 10000); table_.emplace_back("PEPE", 5000); table_.emplace_back("ROSIT", 1000); table_.emplace_back("SAM", 500); table_.emplace_back("PACMQ", 200); table_.emplace_back("PELEC", 100); /* table_.emplace_back("BRY", 1000); table_.emplace_back("USUFO", 500); table_.emplace_back("GLUCA", 100); table_.emplace_back("PARRA", 50); table_.emplace_back("CAGAM", 10); table_.emplace_back("PEPE", 5); table_.emplace_back("ROSIT", 4); table_.emplace_back("SAM", 3); table_.emplace_back("PACMQ", 2); table_.emplace_back("PELEC", 1); */ /* table_.emplace_back("BRY", 5000000); table_.emplace_back("USUFO", 5000000); table_.emplace_back("GLUCA", 5000000); table_.emplace_back("PARRA", 5000000); table_.emplace_back("CAGAM", 5000000); table_.emplace_back("PEPE", 5000000); table_.emplace_back("ROSIT", 5000000); table_.emplace_back("SAM", 5000000); table_.emplace_back("PACMQ", 5000000); table_.emplace_back("PELEC", 5000000); */ sort(); } // Añade un elemento a la tabla auto ManageHiScoreTable::add(const HiScoreEntry& entry) -> int { // 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::ranges::find_if(table_, [&](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 = NO_ENTRY; // No entró en el top 10 } } // Devuelve la posición return position; } // Ordena la tabla void ManageHiScoreTable::sort() { struct { auto operator()(const HiScoreEntry& a, const HiScoreEntry& b) const -> bool { return a.score > b.score; } } score_descending_comparator; std::ranges::sort(table_, score_descending_comparator); } // Carga la tabla desde un fichero auto ManageHiScoreTable::loadFromFile(const std::string& file_path) -> bool { clear(); auto success = true; auto* file = SDL_IOFromFile(file_path.c_str(), "rb"); if (file != nullptr) { table_.clear(); // Limpia la tabla actual // Lee el número de entradas en la tabla int table_size = 0; SDL_ReadIO(file, &table_size, sizeof(int)); // Lee los datos de cada entrada for (int i = 0; i < table_size; ++i) { HiScoreEntry entry; // Lee la puntuación SDL_ReadIO(file, &entry.score, sizeof(int)); // Lee el tamaño del nombre y luego el nombre int name_size = 0; SDL_ReadIO(file, &name_size, sizeof(int)); std::vector name_buffer(name_size + 1); SDL_ReadIO(file, name_buffer.data(), name_size); name_buffer[name_size] = '\0'; // Asegurar el fin de la cadena entry.name = std::string(name_buffer.data()); // Lee el valor de one_credit_complete int occ_value = 0; SDL_ReadIO(file, &occ_value, sizeof(int)); entry.one_credit_complete = (occ_value != 0); // Añade la entrada a la tabla table_.push_back(entry); } SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\nReading file: %s", getFileName(file_path).c_str()); SDL_CloseIO(file); } else { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Unable to load %s file! %s", getFileName(file_path).c_str(), SDL_GetError()); success = false; } return success; } // Guarda la tabla en un fichero auto ManageHiScoreTable::saveToFile(const std::string& file_path) -> bool { auto success = true; auto* file = SDL_IOFromFile(file_path.c_str(), "w+b"); if (file != nullptr) { // Guarda el número de entradas en la tabla int table_size = static_cast(table_.size()); SDL_WriteIO(file, &table_size, sizeof(int)); // Guarda los datos de cada entrada for (int i = 0; i < table_size; ++i) { const HiScoreEntry& entry = table_.at(i); // Guarda la puntuación SDL_WriteIO(file, &entry.score, sizeof(int)); // Guarda el tamaño del nombre y luego el nombre int name_size = static_cast(entry.name.size()); SDL_WriteIO(file, &name_size, sizeof(int)); SDL_WriteIO(file, entry.name.c_str(), name_size); // Guarda el valor de one_credit_complete como un entero (0 o 1) int occ_value = entry.one_credit_complete ? 1 : 0; SDL_WriteIO(file, &occ_value, sizeof(int)); } //SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Writing file: %s", getFileName(file_path).c_str()); Logger::info("Writing file: " + getFileName(file_path)); SDL_CloseIO(file); } else { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Unable to save %s file! %s", getFileName(file_path).c_str(), SDL_GetError()); success = false; } return success; }