I've implemented 2048 game in C++, github link : 2048
For implementing undo operation, i.e. going back to previous state of game, I'm maintaining a matrix for previous board configuration, but if I'm allowing many undo operations consecutively, I can't maintain that number of matrices.
What can be a way to improve this approach?
One way I thought was maintaining only the previous moves(up, down, left or right), but only this information can't help to regenerate the previous state, if I'm missing something in this approach or it can be extended, please suggest a way to do this.
42 Answers
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; }
Implement an history, to store subsequent board status changes.
//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; }
8ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJoa3FvYmWDc36OrqWdp12kvaa%2BwK2gqKZdnrqxuMSmnKeskam2sLqMoqVmamBphW6zwKac