C++ 控制台保存和加载保存的“游戏”
Posted
技术标签:
【中文标题】C++ 控制台保存和加载保存的“游戏”【英文标题】:C++ console Save and load saved "games" 【发布时间】:2017-04-20 06:12:14 【问题描述】:我有一个随机生成的数字网格,大小为gameSize
xgameSize
(用户输入),包含在向量向量中。用户可以输入两个坐标 (x, y),以便将网格内的数字更改为预定义的值。
例如,用户输入 X:0 Y:0 和:
9, 7, 9
9, 6, 8
5, 1, 4
变成:
0, 7, 9 <-- Changes position 0,0 to 0 (the predefined value)
9, 6, 8
5, 1, 4
我正试图弄清楚如何制作它,以便用户可以保存当前的板状态并在以后访问它。我知道我需要以某种方式将游戏 (myGame) 保存到一个文件中,这样我才能访问它并将其再次加载到控制台应用程序中,本质上是保存并重新启动保存的游戏,但我不知道从哪里开始。
【问题讨论】:
我将从输入和输出文件流开始。如果你有一本教科书,应该有一个关于文件输入和输出的部分。然后将您的一系列数字打印到文件中,然后在加载期间将它们读回 如果你想保存/加载一个向量向量,你必须将内部向量大小“烘焙”成文件格式。否则,加载器无法适当地恢复内部向量。在您的情况下,内部向量似乎始终具有相同的大小。这简化了事情:第一,我会使用固定大小的其他东西(例如结构)。具有固定大小的元素向量的第二个文件 I/O 要容易得多(并且可以像已经建议的那样直接使用 I/O 流来完成)。但是,第二个参数。甚至会应用于您当前的数据模型。 【参考方案1】:您可以使用标准库中的 fstream 并将特殊方法添加到您的游戏类,这里是工作示例:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Game
public:
Game(int gameSize) : size(gameSize), field(size, vector<int>(size))
//Randomize(); //generate random numbers
//just filling example for test
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
field[i][j] = i * size + j;
Game(string filename)
Load(filename);
void Load(string filename)
fstream in;
in.open(filename, fstream::in);
in >> size;
field.resize(size, vector<int>(size));
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
in >> field[i][j];
in.close();
void Save(string filename)
fstream out;
out.open(filename, fstream::out);
out << size << endl;
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
out << field[i][j] << " ";
out << endl; //for user friendly look of file
out.close();
private:
int size;
vector<vector<int>> field;
;
int main()
Game game(3);
game.Save("game.txt");
game.Load("game.txt");
game.Save("game2.txt");
return 0;
不要忘记将游戏大小存储在文件中以方便阅读。如果您想加载已存储的游戏,最好将 size 属性添加到您的类并使用另一个构造函数。此外,如果您添加一些检查文件格式是否正确会更好。 如果它们还没有,您可以将所有使轮换的逻辑作为方法添加到 Game 类中。祝你好运!
【讨论】:
【参考方案2】:逐行保存,每行一行:
void Game::save(std::istream& s)
for (const auto& row: myGame)
for (auto cell: row)
s << cell << ' ';
s << '\n';
然后逐行回读并创建行:
void Game::load(std::istream& s)
myGame.clear();
std::string line;
while (std::getline(s, line))
std::istringstream cells(line);
std::vector<int> row;
int cell = 0;
while (cells >> cell)
row.push_back(cell);
myGame.push_back(row);
将行分隔成行意味着您不需要跟踪长度。
使用istream&
和ostream&
参数意味着您不仅可以使用文件,还可以使用任何流,例如stringstream
,或cin
和cout
。
后者可以在调试时派上用场。
【讨论】:
【参考方案3】:首先,您应该阅读 CSV 格式。要求用户为您的游戏设置名称,然后将数组保存到如下文件中: - 每行 1 次保存。 - 行以保存名称开头 - 接下来的两个值代表大小 X 和大小 Y。 - 直到行尾的下一个值表示数组数据。 加载保存游戏的过程如下: - 用户会看到可用保存的列表 - 打算加载哪个存档的用户输入 - 应用程序像这样加载数据:在文件中搜索包含要加载的名称的行,读取大小 x 和大小 y 以初始化该大小的数组,将内容加载到数组中。
【讨论】:
为什么要使用 CSV 来完成如此简单的任务?他还可以使用 json 来描述游戏并从服务器加载它,但我认为它现在超出了项目的范围。 :) 因为他说的是控制台应用程序......而 CSV 代表逗号分隔值。如果是我的应用程序,我会使用 XML,有一些库可以解释 XML,让你的生活更轻松,而使用 CSV 格式意味着你可以从这个应用程序中学到一些东西。同样在一个文件中,您可以存储多个保存...使用您的方法,它可以存储 1 个保存/文件。以上是关于C++ 控制台保存和加载保存的“游戏”的主要内容,如果未能解决你的问题,请参考以下文章
如何将变量保存到新的文本文件中,以便下次程序运行时加载这些变量?