用c++编写康威生命游戏,要求定义class Cell,可以保存到文件或者加载文件,并且用户可以在运行时更改单元格的状态。模拟可以回滚(恢复之前状态)
时间: 2024-03-10 10:45:41 浏览: 23
好的,我可以为您提供一个简单的康威生命游戏的C++实现,以下是代码:
```cpp
#include <iostream>
#include <fstream>
#include <vector>
class Cell {
public:
Cell(bool alive) : alive(alive), prev(alive) {}
bool isAlive() const { return alive; }
void setAlive(bool state) { alive = state; }
void savePrevState() { prev = alive; }
void restorePrevState() { alive = prev; }
private:
bool alive;
bool prev;
};
class GameOfLife {
public:
GameOfLife(size_t width, size_t height) : width(width), height(height) {
board.resize(width * height, Cell(false));
}
void update() {
for (size_t i = 0; i < width; ++i) {
for (size_t j = 0; j < height; ++j) {
int count = countNeighbors(i, j);
if (count == 3) {
setCellState(i, j, true);
} else if (count != 2) {
setCellState(i, j, false);
}
}
}
}
void setCellState(size_t x, size_t y, bool state) {
board[getIndex(x, y)].setAlive(state);
}
bool getCellState(size_t x, size_t y) const {
return board[getIndex(x, y)].isAlive();
}
void saveToFile(const std::string& filename) {
std::ofstream file(filename);
if (!file.is_open()) {
std::cerr << "Error: cannot open file " << filename << std::endl;
return;
}
file << width << ' ' << height << std::endl;
for (size_t j = 0; j < height; ++j) {
for (size_t i = 0; i < width; ++i) {
file << (getCellState(i, j) ? '1' : '0');
}
file << std::endl;
}
file.close();
}
void loadFromFile(const std::string& filename) {
std::ifstream file(filename);
if (!file.is_open()) {
std::cerr << "Error: cannot open file " << filename << std::endl;
return;
}
size_t newWidth, newHeight;
file >> newWidth >> newHeight;
board.clear();
board.resize(newWidth * newHeight, Cell(false));
width = newWidth;
height = newHeight;
for (size_t j = 0; j < height; ++j) {
std::string line;
file >> line;
for (size_t i = 0; i < width; ++i) {
setCellState(i, j, line[i] == '1');
}
}
file.close();
}
void rollback() {
for (size_t i = 0; i < width; ++i) {
for (size_t j = 0; j < height; ++j) {
board[getIndex(i, j)].restorePrevState();
}
}
}
private:
int countNeighbors(size_t x, size_t y) const {
int count = 0;
for (int i = -1; i <= 1; ++i) {
for (int j = -1; j <= 1; ++j) {
if (i == 0 && j == 0) continue;
int nx = x + i;
int ny = y + j;
if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;
if (getCellState(nx, ny)) count++;
}
}
return count;
}
size_t getIndex(size_t x, size_t y) const {
return y * width + x;
}
std::vector<Cell> board;
size_t width;
size_t height;
};
int main() {
GameOfLife game(10, 10);
game.setCellState(3, 3, true);
game.setCellState(4, 3, true);
game.setCellState(5, 3, true);
game.setCellState(4, 4, true);
game.setCellState(4, 5, true);
game.saveToFile("initial_state.txt");
game.update();
game.rollback();
game.loadFromFile("initial_state.txt");
for (size_t j = 0; j < 10; ++j) {
for (size_t i = 0; i < 10; ++i) {
std::cout << (game.getCellState(i, j) ? '*' : ' ');
}
std::cout << std::endl;
}
return 0;
}
```
这个实现定义了一个`Cell`类来表示一个单元格,然后定义了`GameOfLife`类来表示整个生命游戏的状态。`GameOfLife`类的构造函数接受宽度和高度参数,然后初始化一个二维的单元格数组,并将其中的每个单元格初始化为死亡状态。
`GameOfLife`类提供了一些方法来操作单元格数组。例如,`setCellState`和`getCellState`方法用于设置和获取单元格的状态。`update`方法用于更新整个游戏状态。`saveToFile`和`loadFromFile`方法用于将游戏状态保存到文件或从文件中加载。`rollback`方法用于撤销上一次`update`操作。
在这个实现中,我们使用了一个简单的算法来计算每个单元格周围的邻居数量,然后根据规则来更新单元格的状态。在每次更新之前,我们使用`savePrevState`方法保存每个单元格的前一个状态,以便在撤销操作时恢复状态。
在`main`函数中,我们首先创建一个`GameOfLife`对象,并设置一些单元格的状态。然后,我们将当前游戏状态保存到文件`initial_state.txt`中。接下来,我们执行一次更新操作,然后立即执行撤销操作。然后,我们从文件中加载初始状态,并打印整个游戏状态。