C++ 设计模式-备忘录模式

ops/2025/2/26 3:35:52/

游戏存档实现,包括撤销/重做、持久化存储、版本控制和内存管理

#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;
}

功能实现说明:

  1. 撤销/重做系统

    • 使用双栈结构(undoStack + redoStack)
    • undo() 保留最近两个状态以实现状态对比
    • 每次保存时清空重做栈
  2. 持久化存储

    • 使用CSV格式存储:level,health,weapon,timestamp
    • 支持从文件恢复完整历史记录
  3. 版本控制

    • 每个存档包含精确到秒的时间戳
    • showHistory() 显示带时间的版本信息
  4. 内存优化

    • 限制最大存档数量(MAX_SAVES = 5)
    • 自动移除最早的存档
  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)

http://www.ppmy.cn/ops/161340.html

相关文章

游戏引擎学习第120天

仓库:https://gitee.com/mrxiao_com/2d_game_3 上次回顾&#xff1a;周期计数代码 我们正在进行一个项目的代码优化工作&#xff0c;目标是提高性能。当前正在优化某个特定的代码片段&#xff0c;已经将其执行周期减少到48个周期。为了实现这一目标&#xff0c;我们设计了一个…

【初探数据结构】时间复杂度和空间复杂度

&#x1f4ac; 欢迎讨论&#xff1a;在阅读过程中有任何疑问&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;如果你觉得这篇文章对你有帮助&#xff0c;记得点赞、收藏&#xff0c;并分享给更多对数据结构感…

Redis--模糊查询--方法实例

原文网址&#xff1a;Redis–模糊查询–方法/实例_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Redis模糊查询的方法。 官网网址 https://redis.io/commands/keys/ https://redis.io/commands/scan/ Redis模糊查询键的方法 Redis提供了两种模糊查询键的方法&#xff…

MySQL数据库连接池泄露导致MySQL Server超时关闭连接

前言 最近做项目&#xff0c;发现老项目出现xxx&#xff0c;这个错误其实很简单&#xff0c;出现在MySQL数据库Server端对长时间没有使用的client连接执行清楚处理&#xff0c;因为是druid数据库&#xff0c;且在github也出现这样的issue&#xff1a;The last packet successf…

14.8 Auto-GPT 自主智能体设计解密:构建具备长期记忆的智能决策系统

Auto-GPT 自主智能体设计解密:构建具备长期记忆的智能决策系统 关键词:Auto-GPT 架构设计、自主智能体开发、LangChain Agents、长期记忆系统、工具链编排 1. 自主智能体的核心架构设计 Auto-GPT 系统架构图解: #mermaid-svg-NuDU1eo6sXqhA6Ve {font-family:"trebuch…

推送项目 之 解决冲突

文章目录 为什么会发生冲突&#xff1f;如何解决这些冲突&#xff1f;1. **查看冲突文件**2. **解决二进制文件冲突**3. **解决文本文件冲突**4. **标记冲突已解决**5. **完成合并**6. **推送更改** 注意事项总结 问题&#xff1a;我们在git pusll拉取远程仓库的代码到本地对比…

Nginx代理ElasticSearch

1、将ES的账号:密码通过Base64加密 假设账号密码如下&#xff1a; 账号&#xff1a;elastic密码&#xff1a;elastichuayunworld.com echo -n elastic:elastichuayunworld.com | base64 ZWxhc3RpYzplbGFzdGljQGh1YXl1bndvcmxkLmNvbQ2、在 Nginx 配置中传递认证信息 locatio…

【量化科普】Sharpe Ratio,夏普比率

【量化科普】Sharpe Ratio&#xff0c;夏普比率 &#x1f680;&#x1f680;&#x1f680;量化软件开通&#x1f680;&#x1f680;&#x1f680; &#x1f680;&#x1f680;&#x1f680;量化实战教程&#x1f680;&#x1f680;&#x1f680; 在量化投资领域&#xff0c;…