Updated game structure
This commit is contained in:
81
src/persistence/Scores.cpp
Normal file
81
src/persistence/Scores.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
// Scores.cpp - Implementation of ScoreManager (copied into src/persistence)
|
||||
#include "Scores.h"
|
||||
#include <SDL3/SDL.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
ScoreManager::ScoreManager(size_t maxScores) : maxEntries(maxScores) {}
|
||||
|
||||
std::string ScoreManager::filePath() const {
|
||||
static std::string path; if (!path.empty()) return path;
|
||||
char* base = SDL_GetPrefPath("example","tetris_sdl3");
|
||||
if (base) { path = std::string(base)+"highscores.txt"; SDL_free(base);} else path="highscores.txt";
|
||||
return path;
|
||||
}
|
||||
|
||||
void ScoreManager::load() {
|
||||
scores.clear();
|
||||
std::ifstream f(filePath());
|
||||
if (!f) {
|
||||
// Create sample high scores if file doesn't exist
|
||||
createSampleScores();
|
||||
save();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
while (std::getline(f, line)) {
|
||||
std::istringstream iss(line);
|
||||
ScoreEntry e;
|
||||
iss >> e.score >> e.lines >> e.level >> e.timeSec;
|
||||
if (iss) {
|
||||
// Try to read name (rest of line after timeSec)
|
||||
std::string remaining;
|
||||
std::getline(iss, remaining);
|
||||
if (!remaining.empty() && remaining[0] == ' ') {
|
||||
e.name = remaining.substr(1); // Remove leading space
|
||||
}
|
||||
scores.push_back(e);
|
||||
}
|
||||
if (scores.size() >= maxEntries) break;
|
||||
}
|
||||
|
||||
if (scores.empty()) {
|
||||
createSampleScores();
|
||||
save();
|
||||
}
|
||||
|
||||
std::sort(scores.begin(), scores.end(), [](auto&a,auto&b){return a.score>b.score;});
|
||||
}
|
||||
|
||||
void ScoreManager::save() const {
|
||||
std::ofstream f(filePath(), std::ios::trunc);
|
||||
for (auto &e : scores) {
|
||||
f << e.score << ' ' << e.lines << ' ' << e.level << ' ' << e.timeSec << ' ' << e.name << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void ScoreManager::submit(int score, int lines, int level, double timeSec) {
|
||||
scores.push_back(ScoreEntry{score,lines,level,timeSec});
|
||||
std::sort(scores.begin(), scores.end(), [](auto&a,auto&b){return a.score>b.score;});
|
||||
if (scores.size()>maxEntries) scores.resize(maxEntries);
|
||||
save();
|
||||
}
|
||||
|
||||
void ScoreManager::createSampleScores() {
|
||||
scores = {
|
||||
{159840, 189, 14, 972, "GREGOR"},
|
||||
{156340, 132, 12, 714, "GREGOR"},
|
||||
{155219, 125, 12, 696, "GREGOR"},
|
||||
{141823, 123, 10, 710, "GREGOR"},
|
||||
{140079, 71, 11, 410, "GREGOR"},
|
||||
{116012, 121, 10, 619, "GREGOR"},
|
||||
{112643, 137, 13, 689, "GREGOR"},
|
||||
{99190, 61, 10, 378, "GREGOR"},
|
||||
{93648, 107, 10, 629, "GREGOR"},
|
||||
{89041, 115, 10, 618, "GREGOR"},
|
||||
{88600, 55, 9, 354, "GREGOR"},
|
||||
{86346, 141, 13, 723, "GREGOR"}
|
||||
};
|
||||
}
|
||||
20
src/persistence/Scores.h
Normal file
20
src/persistence/Scores.h
Normal file
@ -0,0 +1,20 @@
|
||||
// Scores.h - High score persistence manager
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct ScoreEntry { int score{}; int lines{}; int level{}; double timeSec{}; std::string name{"PLAYER"}; };
|
||||
|
||||
class ScoreManager {
|
||||
public:
|
||||
explicit ScoreManager(size_t maxScores = 12);
|
||||
void load();
|
||||
void save() const;
|
||||
void submit(int score, int lines, int level, double timeSec);
|
||||
const std::vector<ScoreEntry>& all() const { return scores; }
|
||||
private:
|
||||
std::vector<ScoreEntry> scores;
|
||||
size_t maxEntries;
|
||||
std::string filePath() const; // resolve path (SDL pref path or local)
|
||||
void createSampleScores(); // create sample high scores
|
||||
};
|
||||
Reference in New Issue
Block a user