Я реализовал игру 2048 на C ++, ссылка на github: 2048
Для реализации операции отмены, т. Е. Возвращаясь к предыдущему состоянию игры, я поддерживаю матрицу для предыдущей конфигурации платы, но если я разрешаю много операций отмены последовательно, я не могу поддерживать это количество матриц.
Что может быть способом улучшить этот подход?
Я думал, что одним из способов было сохранение только предыдущих ходов (вверх, вниз, влево или вправо), но только эта информация не может помочь восстановить предыдущее состояние, если я что-то упустил в этом подходе или его можно расширить, пожалуйста, предложить способ сделать это.
Вы можете сохранить текущее состояние доски в стек, так что каждый раз, когда пользователь делает ход, который изменит состояние доски, просто поместите его в стек, чтобы получить стек, заполненный матрицей текущего состояния досок ходов пользователя и заказал с недавнего наверху. Так что, когда вы хотите отменить их последний ход, просто извлеките из стека, который даст вам их последнюю операцию.
...
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;
}
Реализуйте историю, чтобы сохранить последующие изменения статуса платы.
//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;
}