我已经用 C++ 实现了 2048 游戏,github 链接:2048
为了实现撤销操作,即回到之前的游戏状态,我维护了一个用于之前的棋盘配置的矩阵,但是如果我允许连续进行许多撤销操作,我就无法维护那个数量的矩阵。
有什么方法可以改进这种方法?
我认为的一种方法是只保留以前的移动(上、下、左或右),但只有这些信息无助于重新生成以前的状态,如果我在这种方法中遗漏了什么或者可以扩展,请建议一种方法来做到这一点。
我已经用 C++ 实现了 2048 游戏,github 链接:2048
为了实现撤销操作,即回到之前的游戏状态,我维护了一个用于之前的棋盘配置的矩阵,但是如果我允许连续进行许多撤销操作,我就无法维护那个数量的矩阵。
有什么方法可以改进这种方法?
我认为的一种方法是只保留以前的移动(上、下、左或右),但只有这些信息无助于重新生成以前的状态,如果我在这种方法中遗漏了什么或者可以扩展,请建议一种方法来做到这一点。
实施历史记录,以存储后续板状态更改。
//maximum history size (can be whatever reasonable value)
const int MAX_UNDO = 2048;
//give a shorter name to the type used to store the board status
typedef std::array<int, 16> snapshot;
//use a double ended queue to store the board statuses
std::deque<snapshot> history;
//this function saves the current status, has to be called each time
//the board status changes, i.e. after the board initialization
//and after every player move
void save()
{
//make a copy of g, the current status
snapshot f;
std::copy(&g[0][0], &g[0][0] + 16, f.begin());
//push the copy on top
history.push_back(f);
//check history size
if(history.size() > MAX_UNDO)
{
//remove one element at the bottom end
history.pop_front();
}
}
bool undo()
{
//history must hold at least one element
//other than the current status copy
if(history.size() > 1)
{
//the top element of the queue always holds a copy of the
//current board status: remove it first
history.pop_back();
//now the top element is the previous status copy
snapshot f = history.back();
//copy it back to g
std::copy(f.begin(), f.end(), &g[0][0]);
//undo operation succedeed
return true;
}
//undo operation failed
return false;
}
You can store the board's current state into a stack, so every time the user makes a move, which will change the board state, just put it into a stack so you get a stack full of with matrix of board's current state of user's moves and ordered from recent one being on the top. So when you want to undo their latest move just pop from stack which will give you their latest operation.
...
std::stack<std::array<int, 16>> boardStates;
std::array<16, int> currentBoardState;
// whenever user makes a move
makeMove(currentBoardState)
//when they want to undo
tempBoardState = undoMove();
if(tempBoardState != nullptr)
{
currentBoardState = tempBoardState;
}
else
{
std::cout << "No previous move available" << std::endl
}
...
void makeMove(std::array<int, 16> currentState)
{
boardStates.push(currentState);
}
std::array<int, 16> undoMove()
{
if(!boardStates.empty())
{
return boardStates.pop();
}
return nullptr;
}