Undo Operation Implementation in 2048 Game

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.

4

2 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;
}
8

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

David Miller

David Miller

Executive Financial & Market Analyst

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.

Share this article
Twitter Facebook Pinterest