193 lines
5.1 KiB
C++
193 lines
5.1 KiB
C++
#include "game/gameplay/stats.hpp"
|
|
|
|
#include <fstream> // Para basic_ostream, basic_ifstream, basic_istream
|
|
#include <sstream> // Para basic_stringstream
|
|
#include <utility>
|
|
|
|
#include "game/options.hpp" // Para Options, OptionsStats, options
|
|
|
|
// Constructor
|
|
Stats::Stats(std::string file, std::string buffer)
|
|
: buffer_path_(std::move(buffer)),
|
|
file_path_(std::move(file)) {}
|
|
|
|
// Destructor
|
|
Stats::~Stats() {
|
|
// Vuelca los datos del buffer en la lista de estadisticas
|
|
updateListFromBuffer();
|
|
|
|
// Calcula cual es la habitación con más muertes
|
|
checkWorstNightmare();
|
|
|
|
// Guarda las estadísticas
|
|
saveToFile(buffer_path_, buffer_list_);
|
|
saveToFile(file_path_, list_);
|
|
|
|
buffer_list_.clear();
|
|
list_.clear();
|
|
dictionary_.clear();
|
|
}
|
|
|
|
// Inicializador
|
|
void Stats::init()
|
|
// Se debe llamar a este procedimiento una vez se haya creado el diccionario numero-nombre
|
|
{
|
|
loadFromFile(buffer_path_, buffer_list_);
|
|
loadFromFile(file_path_, list_);
|
|
|
|
// Vuelca los datos del buffer en la lista de estadisticas
|
|
updateListFromBuffer();
|
|
}
|
|
|
|
// Añade una muerte a las estadisticas
|
|
void Stats::addDeath(const std::string& name) {
|
|
// Primero busca si ya hay una entrada con ese nombre
|
|
const int INDEX = findByName(name, buffer_list_);
|
|
if (INDEX != -1) {
|
|
buffer_list_[INDEX].died++;
|
|
}
|
|
|
|
// En caso contrario crea la entrada
|
|
else {
|
|
StatsData item;
|
|
item.name = name;
|
|
item.visited = 0;
|
|
item.died = 1;
|
|
buffer_list_.push_back(item);
|
|
}
|
|
}
|
|
|
|
// Añade una visita a las estadisticas
|
|
void Stats::addVisit(const std::string& name) {
|
|
// Primero busca si ya hay una entrada con ese nombre
|
|
const int INDEX = findByName(name, buffer_list_);
|
|
if (INDEX != -1) {
|
|
buffer_list_[INDEX].visited++;
|
|
}
|
|
|
|
// En caso contrario crea la entrada
|
|
else {
|
|
StatsData item;
|
|
item.name = name;
|
|
item.visited = 1;
|
|
item.died = 0;
|
|
buffer_list_.push_back(item);
|
|
}
|
|
}
|
|
|
|
// Busca una entrada en la lista por nombre
|
|
auto Stats::findByName(const std::string& name, const std::vector<StatsData>& list) -> int {
|
|
int i = 0;
|
|
|
|
for (const auto& l : list) {
|
|
if (l.name == name) {
|
|
return i;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
// Carga las estadisticas desde un fichero
|
|
auto Stats::loadFromFile(const std::string& file_path, std::vector<StatsData>& list) -> bool {
|
|
list.clear();
|
|
|
|
// Indicador de éxito en la carga
|
|
bool success = true;
|
|
|
|
// Variables para manejar el fichero
|
|
std::ifstream file(file_path);
|
|
|
|
// Si el fichero se puede abrir
|
|
if (file.good()) {
|
|
std::string line;
|
|
// Procesa el fichero linea a linea
|
|
while (std::getline(file, line)) {
|
|
// Comprueba que la linea no sea un comentario
|
|
if (line.substr(0, 1) != "#") {
|
|
StatsData stat;
|
|
std::stringstream ss(line);
|
|
std::string tmp;
|
|
|
|
// Obtiene el nombre
|
|
getline(ss, tmp, ';');
|
|
stat.name = tmp;
|
|
|
|
// Obtiene las visitas
|
|
getline(ss, tmp, ';');
|
|
stat.visited = std::stoi(tmp);
|
|
|
|
// Obtiene las muertes
|
|
getline(ss, tmp, ';');
|
|
stat.died = std::stoi(tmp);
|
|
|
|
list.push_back(stat);
|
|
}
|
|
}
|
|
|
|
// Cierra el fichero
|
|
file.close();
|
|
}
|
|
|
|
// El fichero no existe
|
|
else {
|
|
// Crea el fichero con los valores por defecto
|
|
saveToFile(file_path, list);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
// Guarda las estadisticas en un fichero
|
|
void Stats::saveToFile(const std::string& file_path, const std::vector<StatsData>& list) {
|
|
// Crea y abre el fichero de texto
|
|
std::ofstream file(file_path);
|
|
|
|
// Escribe en el fichero
|
|
file << "# ROOM NAME;VISITS;DEATHS" << '\n';
|
|
for (const auto& item : list) {
|
|
file << item.name << ";" << item.visited << ";" << item.died << '\n';
|
|
}
|
|
|
|
// Cierra el fichero
|
|
file.close();
|
|
}
|
|
|
|
// Calcula cual es la habitación con más muertes
|
|
void Stats::checkWorstNightmare() {
|
|
int deaths = 0;
|
|
for (const auto& item : list_) {
|
|
if (item.died > deaths) {
|
|
deaths = item.died;
|
|
Options::stats.worst_nightmare = item.name;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Añade una entrada al diccionario
|
|
void Stats::addDictionary(const std::string& number, const std::string& name) {
|
|
dictionary_.push_back({number, name});
|
|
}
|
|
|
|
// Vuelca los datos del buffer en la lista de estadisticas
|
|
void Stats::updateListFromBuffer() {
|
|
// Actualiza list_ desde buffer_list_
|
|
for (const auto& buffer : buffer_list_) {
|
|
int index = findByName(buffer.name, list_);
|
|
|
|
if (index != -1) { // Encontrado. Aumenta sus estadisticas
|
|
list_[index].visited += buffer.visited;
|
|
list_[index].died += buffer.died;
|
|
} else { // En caso contrario crea la entrada
|
|
StatsData item;
|
|
item.name = buffer.name;
|
|
item.visited = buffer.visited;
|
|
item.died = buffer.died;
|
|
list_.push_back(item);
|
|
}
|
|
}
|
|
|
|
saveToFile(buffer_path_, buffer_list_);
|
|
saveToFile(file_path_, list_);
|
|
} |