1 Goals To build a Stack class by using an stl template. To be able to undo and redo moves. 2 Changes to Other Classes Changes to the Game class. The Game::run() function displays a menu and accepts selections, which are processed by a switch. The switch should call action functions to carry out most of the user's choices. Try to limit the code that is actually inside teach case to three lines. If you have not already done so, move longer blocks of code out of the switch into separate functions. Activate menu options undo and redo. Also instantiate two stacks of BoardState*s: the undo stack and the redo stack. Use the Stack class dened below, which is adapted from the stl Stack template. The undo stack always holds a copy of the current state of the game. The redo stack holds states that have been undone, until they are ready to be redone. The Game class has custody of these dynamically allocated objects and is responsible for deallocating them whenever one is discarded. Every time you make a move or turn o a possibility, another BoardState will be pushed onto the undo stack. When you ask to undo or redo an action, a BoardState will be popped from one of the stacks and used to update the state of the Board. When you stop doing undos and redos and again call move or turn , the redo history becomes invalid. Thus, any call to move or turno must zap (empty) the redo stack. At the end of a game, the undo stack contains a complete history of your successful moves. (This history could be written to a le if anyone was interested in it.) Add to the actions for the Move menu item. Immediately after the user makes a move, do the following: Create a new BoardState object, initialized to the state after the move. Push the pointer onto the undo stack. Clear the redo stack. Implement the undo menu item, keeping in mind that you can't undo unless the stack has 2 or more BoardStates. Pop one BoardState* o the undo stack, then Push the pointer onto the redo stack. Then restore the Board state to the state on top of the undo stack, as dened below. Implement the redo menu item: Return without doing anything if the redo stack is empty. Pop one BoardState* o the redo stack, then Push the pointer onto the undo stack. Then restore the Board state to the state on top of the undo stack, as dened below. 9: undo and redo CSCI 4526 / 6626 Fall 2016 2 Changes to the Board class. Add a function restoreState( BoardState* ). This will loop through the 81 squares in the parameter BoardState and copy the information into the State portion of each Square. Call this from the Game class after either an undo or a redo. 3 The Stack Class Implementing a Stack. The standard template library has a template named stack<T that does approximately (but not exactly) what we want in this application. However, it is very easy to adapt the vector<T template and create a stack with the right functionality. Our strategy will be to instantiate the stl template as vector<BoardState* and at the same time, on the same line, derive the class Stack from it. Private derivation is needed to close o access to many unwanted vector<T functions. However, private derivation forces us to dene, in Stack, all of the functions we want to keep. In the derived class, you will need these functions; dene them all as inline functions: Constructor and destructor. void pop(); Delegate to vector::pop_back() BoardState* top(); Delegate to vector::top() void push( BoardState* ); Delegate to vector::push_back( BoardState* ) int size(); Return the number of BoardStates on the stack (in the vector). void zap(); Empty the entire stack by popping everything o it. Remember that this involves freeing dynamic memory. This Stack class is an adapter class: it adapts vector to our needs by adding, removing, and renaming functions. The rst three functions, above, rename the functions inherited from vector. To implement them, simply call the appropriate function from the vector class. One function, size(), has the same name as the underlying function in vector. For that one function, you must use the :: operator to call the size() function from the base class. (Otherwise, an attempt to delegate becomes an innite recursion and your program will end with a segmentation error. I unthinkingly tried it. Bad news!)