Reputation: 695
I'm working on a game, in which a player can move around a board/grid. It has moveLeft(), moveRight(), moveUp(), and moveDown() methods which move the player 1 space at a time around the board.
I'm trying to plan out my approach to required Undo/Redo functionality on the player movement (e.g. if player had gone one space to left, and Undo was called, player would move one space to right). I'm a student, and looking into Stacks.
However, when planning the logic out on paper before programming (I find this helps me when undertaking homework), I don't know if Stacks would be appropriate based on the following problem....
When each move method is called, a string 'Up', 'Down', 'Left', 'Right' is added to Stack 1, dependent on the method called. This tracks the players movement around the board.
If undo() is called, the string on top of Stack 1 is removed, and added to a new stack, 'Stack 2'. This is used to track 'undone' moves, so that redo() has a path to follow.
If redo() is called, the string on Stack 2 is removed, and back added to Stack 1.
This works perfectly, but only if you call Redo() for exactly the same amount of times as Undo() and directly after it.
E.g.:
I've been trying to work on the logic behind this in isolation for the last 4 hrs! Any advice appreciated. Namely - based on the above, is it still possible to do what I need to do with Stacks, and I need to find a work around to the problem? Or should I abandon, because it is not possible.
Upvotes: 3
Views: 2022
Reputation: 5782
If you don't want to use Stacks
because you're unsure when to clear the undo Stack
, you can do this with a List
. Then, your logic can be maintained in a similar fashion:
Then, your example is:
Upvotes: 1
Reputation: 431
It is simple to fix. Basically, a Redo is valid only if immediate previous action was an Undo.
One solution is : When the player makes a move then empty the Stack 2 (the Undo stack, that is used to Redo).
Other Solution: Defer stack 2 clearance to later. Maintain a boolean flag that tracks if previous action was an Undo (say boolean isRecentActionUndo), that should always represent if previous action was an Undo, by setting it to true on every call to Undo() and setting it to false on every call to Move(). Check this flag in Redo().
if(isRecentActionUndo) {
// perform redo
} else {
// clear stack 2
}
There could be other better solutions to achieve the same, to perform a valid Redo().
Upvotes: 0
Reputation: 3011
In step 3
Player makes 4 more moves: (Stack 1 now has 7 strings, Stack 2 still has 1 string)
you must empty second stack.
Upvotes: 0
Reputation: 199
Think of it this way.. The whole idea of undo and redo lies around the state of your application (program). The Undo means you want to go immediately previous state of your application; similarly it is the case with Redo. Yes the stack is best solution to keep your previous state saved. For an Undo you do a pop and push it to another stack. Use the other stack for redo operation. You might want to set a limit for undo and redo. How you approach to save the state of your application is up to you.
Upvotes: 0