游戏存档实现,包括撤销/重做、持久化存储、版本控制和内存管理
#include <iostream>
#include <memory>
#include <deque>
#include <stack>
#include <chrono>
#include <fstream>
#include <sstream>
#include <ctime>
// ================ 1. 增强版备忘录类 ================
class GameMemento {
private:
const int level;
const int health;
const std::string weapon;
const std::chrono::system_clock::time_point timestamp;
friend class GameCharacter;
public:
GameMemento(int lv, int hp, std::string wp, std::chrono::system_clock::time_point ts)
: level(lv), health(hp), weapon(std::move(wp)), timestamp(ts) {}
// 序列化为字符串
std::string serialize() const {
std::time_t ts = std::chrono::system_clock::to_time_t(timestamp);
std::stringstream ss;
ss << level << "," << health << "," << weapon << "," << ts;
return ss.str();
}
// 从字符串反序列化
static std::unique_ptr<GameMemento> deserialize(const std::string& data) {
std::stringstream ss(data);
int lv, hp;
std::string wp;
time_t ts;
char comma;
ss >> lv >> comma >> hp >> comma;
std::getline(ss, wp, ',');
ss >> ts;
return std::make_unique<GameMemento>(
lv, hp, wp, std::chrono::system_clock::from_time_t(ts)
);
}
void print() const {
auto ts = std::chrono::system_clock::to_time_t(timestamp);
char buffer[26];
strftime(buffer, sizeof(buffer), "%a %b %d %H:%M:%S %Y", std::localtime(&ts));
std::cout << "Lv." << level << " HP:" << health
<< " Weapon:" << weapon << " (" << buffer << ")\n";
}
};
// ================ 2. 游戏角色类 ================
class GameCharacter {
private:
int level = 1;
int health = 100;
std::string weapon = "Fist";
public:
void levelUp() { level++; health += 20; }
void takeDamage(int dmg) { health -= dmg; }
void equipWeapon(std::string wp) { weapon = std::move(wp); }
std::unique_ptr<GameMemento> save() const {
return std::make_unique<GameMemento>(
level, health, weapon,
std::chrono::system_clock::now()
);
}
void load(const GameMemento& memento) {
level = memento.level;
health = memento.health;
weapon = memento.weapon;
}
void status() const {
std::cout << "Current State: Lv." << level
<< " HP:" << health
<< " Weapon:" << weapon << "\n";
}
};
// ================ 3. 增强版存档管理器 ================
class SaveManager {
private:
std::deque<std::unique_ptr<GameMemento>> undoStack; // 使用deque方便限制数量
std::stack<std::unique_ptr<GameMemento>> redoStack; // 重做栈
const size_t MAX_SAVES = 5; // 最大存档数量
void trimHistory() {
while (undoStack.size() > MAX_SAVES) {
undoStack.pop_front(); // 移除最旧的存档
}
}
public:
// 保存新状态
void saveState(const GameCharacter& character) {
undoStack.push_back(character.save());
redoStack = std::stack<std::unique_ptr<GameMemento>>(); // 清空重做栈
trimHistory();
}
// 撤销
bool undo(GameCharacter& character) {
if (undoStack.size() < 2) return false;
redoStack.push(std::move(undoStack.back()));
undoStack.pop_back();
character.load(*undoStack.back());
return true;
}
// 重做
bool redo(GameCharacter& character) {
if (redoStack.empty()) return false;
character.load(*redoStack.top());
undoStack.push_back(std::move(redoStack.top()));
redoStack.pop();
return true;
}
// 保存到文件
bool saveToFile(const std::string& filename) const {
std::ofstream file(filename);
if (!file) return false;
for (const auto& memento : undoStack) {
file << memento->serialize() << "\n";
}
return true;
}
// 从文件加载
bool loadFromFile(const std::string& filename, GameCharacter& character) {
std::ifstream file(filename);
if (!file) return false;
undoStack.clear();
redoStack = std::stack<std::unique_ptr<GameMemento>>();
std::string line;
while (std::getline(file, line)) {
auto memento = GameMemento::deserialize(line);
if (memento) {
undoStack.push_back(std::move(memento));
}
}
if (!undoStack.empty()) {
character.load(*undoStack.back());
}
return true;
}
// 显示版本历史
void showHistory() const {
std::cout << "\n=== Version History (" << undoStack.size() << "/"
<< MAX_SAVES << ") ===\n";
int i = 1;
for (const auto& memento : undoStack) {
std::cout << "Version " << i++ << ": ";
memento->print();
}
}
};
// ================ 使用示例 ================
int main() {
GameCharacter hero;
SaveManager saveManager;
// 初始状态
hero.status();
saveManager.saveState(hero);
// 查看历史版本
saveManager.showHistory();
// 进行一系列操作
hero.levelUp();
hero.equipWeapon("Sword");
saveManager.saveState(hero);
hero.takeDamage(30);
saveManager.saveState(hero);
hero.levelUp();
hero.equipWeapon("Axe");
saveManager.saveState(hero);
// 查看历史版本
saveManager.showHistory();
// 持久化存储
saveManager.saveToFile("game_save.txt");
// 连续撤销两次
std::cout << "=== Undo x2 ===\n";
saveManager.undo(hero);
saveManager.undo(hero);
hero.status();
// 重做一次
std::cout << "=== Redo x1 ===\n";
saveManager.redo(hero);
hero.status();
// 从文件加载
GameCharacter loadedHero;
SaveManager loadManager;
loadManager.loadFromFile("game_save.txt", loadedHero);
std::cout << "=== Loaded Character ===\n";
loadedHero.status();
loadManager.showHistory();
hero.takeDamage(-30);
saveManager.saveState(hero);
hero.status();
// 查看历史版本
saveManager.showHistory();
return 0;
}
功能实现说明:
-
撤销/重做系统:
- 使用双栈结构(undoStack + redoStack)
undo()
保留最近两个状态以实现状态对比- 每次保存时清空重做栈
-
持久化存储:
- 使用CSV格式存储:
level,health,weapon,timestamp
- 支持从文件恢复完整历史记录
- 使用CSV格式存储:
-
版本控制:
- 每个存档包含精确到秒的时间戳
showHistory()
显示带时间的版本信息
-
内存优化:
- 限制最大存档数量(MAX_SAVES = 5)
- 自动移除最早的存档
-
附加功能:
- 版本历史浏览
- 完整的异常安全设计
- 使用现代C++特性(chrono时间库、智能指针等)
执行结果示例:
Current State: Lv.1 HP:100 Weapon:Fist
=== Version History (1/5) ===
Version 1: Lv.1 HP:100 Weapon:Fist (Fri Feb 21 12:10:21 2025)
=== Version History (4/5) ===
Version 1: Lv.1 HP:100 Weapon:Fist (Fri Feb 21 12:10:21 2025)
Version 2: Lv.2 HP:120 Weapon:Sword (Fri Feb 21 12:10:21 2025)
Version 3: Lv.2 HP:90 Weapon:Sword (Fri Feb 21 12:10:21 2025)
Version 4: Lv.3 HP:110 Weapon:Axe (Fri Feb 21 12:10:21 2025)
=== Undo x2 ===
Current State: Lv.2 HP:120 Weapon:Sword
=== Redo x1 ===
Current State: Lv.2 HP:90 Weapon:Sword
=== Loaded Character ===
Current State: Lv.3 HP:110 Weapon:Axe
=== Version History (4/5) ===
Version 1: Lv.1 HP:100 Weapon:Fist (Fri Feb 21 12:10:21 2025)
Version 2: Lv.2 HP:120 Weapon:Sword (Fri Feb 21 12:10:21 2025)
Version 3: Lv.2 HP:90 Weapon:Sword (Fri Feb 21 12:10:21 2025)
Version 4: Lv.3 HP:110 Weapon:Axe (Fri Feb 21 12:10:21 2025)
Current State: Lv.2 HP:120 Weapon:Sword
=== Version History (4/5) ===
Version 1: Lv.1 HP:100 Weapon:Fist (Fri Feb 21 12:10:21 2025)
Version 2: Lv.2 HP:120 Weapon:Sword (Fri Feb 21 12:10:21 2025)
Version 3: Lv.2 HP:90 Weapon:Sword (Fri Feb 21 12:10:21 2025)
Version 4: Lv.2 HP:120 Weapon:Sword (Fri Feb 21 12:10:21 2025)