BubbleBobbleRemake / BubbleBobble / GameState.h
GameState.h
Raw
#pragma once
#include "Singleton.h"

#include <fstream>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm> 

namespace dae
{
	enum class GameMode : unsigned
	{
		SINGLEPLAYER,
		COOP,
		VERSUS
	};

	class GameState final : public Singleton<GameState>
	{
	public:
		void SetLevelId(int levelId) { m_LevelId = levelId; }

		void SetPlayer1Score(int score) { m_Player1Score = score; }
		void SetPlayer2Score(int score) { m_Player2Score = score; }

		void SetPlayer1Lives(int lives) { m_Player1Lives = lives; }
		void SetPlayer2Lives(int lives) { m_Player2Lives = lives; }

		void SetHighScore(int score) { m_CurrentHighScore = score; }
		void SetGameMode(GameMode gameMode) { m_GameMode = gameMode; }

		int GetLevelId() const { return m_LevelId; }

		int GetPlayer1Lives() const { return m_Player1Lives; }
		int GetPlayer2Lives() const { return m_Player2Lives; }

		int GetPlayer1Score() const { return m_Player1Score; }
		int GetPlayer2Score() const { return m_Player2Score; }

		void LoadHighScores()
		{
			// Open the file
			std::ifstream file("../Data/Highscores/Highscores.txt");
			if (!file.is_open()) {
				std::cout << "Failed to open Highscores.txt" << std::endl;
				return;
			}

			std::string line;
			while (getline(file, line)) {
				// Split the line by ','
				size_t commaPos = line.find(',');
				if (commaPos != std::string::npos) {
					std::string name = line.substr(0, commaPos);
					int score = std::stoi(line.substr(commaPos + 1));
					m_Highscores.push_back({ name, score });
				}
			}
			file.close();

			m_CurrentHighScore = m_Highscores[4].second;
		}

		std::vector<std::pair<std::string, int>> GetSavedHighScores() const
		{
			return m_Highscores;
		}

		void SaveHighScores() {
			std::ofstream file("../Data/Highscores/Highscores.txt");
			if (!file.is_open()) {
				std::cerr << "Failed to open Highscores.txt for writing" << std::endl;
				return;
			}

			for (const auto& [name, score] : m_Highscores) {
				file << name << "," << score << "\n";
			}

			file.close();
		}

		int AddHighScore(const std::string& name, int score)
		{
			m_Highscores.push_back({ name, score });

			// Sort
			std::sort(m_Highscores.begin(), m_Highscores.end(), [](const auto& a, const auto& b) {
				return a.second > b.second; // 'second' refers to the score in the pair
				});

			// Save index where the score was added
			auto it = std::find(m_Highscores.begin(), m_Highscores.end(), std::make_pair(name, score));
			int position = (it != m_Highscores.end()) ? static_cast<int>(std::distance(m_Highscores.begin(), it)) : -1;

			// Trim
			if (m_Highscores.size() > 5) {
				m_Highscores.resize(5);
			}

			SaveHighScores();

			// return the saved index or -1 if new score was trimmed
			if (position >= 5) {
				return -1;
			}

			return position;
		}

		int GetHighScore() const { return m_CurrentHighScore; }
		GameMode GetGameMode() const { return m_GameMode; }
	private:
		friend class Singleton<GameState>;
		GameState() = default;

		int m_LevelId{};

		int m_Player1Lives{};
		int m_Player2Lives{};

		int m_Player1Score{};
		int m_Player2Score{};

		int m_CurrentHighScore{};

		GameMode m_GameMode{ GameMode::SINGLEPLAYER };

		std::vector<std::pair<std::string, int>> m_Highscores;
	};
}