Following the pattern we have done before on this project, we now will write the class methods that use this new hierarchy. In this case, we're going to do something a little unusual. We're going to answer the actual method names to execute when an undo action takes place.
On the ReverseLaserGameAction class add the following two class methods.
reverseActionClassFor: aSymbol
^self subclasses detect: [:cls | cls actionSymbol = aSymbol]
reverseActionSymbolFor: aSymbol
| cls |
cls := self reverseActionClassFor: aSymbol.
^cls reverseActionSymbol
We will use the #reverseActionSymbolFor: class method to decide which methods to execute when we perform an undo action.
Time to write a unit test. Add the following instance method to our GridTestCase class.
testUndoActions
| undoAction |
undoAction := ReverseLaserGameAction reverseActionSymbolFor: #north.
self should: [undoAction = #pushCellSouthFromLocation:].
undoAction := ReverseLaserGameAction reverseActionSymbolFor: #east.
self should: [undoAction = #pushCellWestFromLocation:].
undoAction := ReverseLaserGameAction reverseActionSymbolFor: #south.
self should: [undoAction = #pushCellNorthFromLocation:].
undoAction := ReverseLaserGameAction reverseActionSymbolFor: #west.
self should: [undoAction = #pushCellEastFromLocation:].
undoAction := ReverseLaserGameAction reverseActionSymbolFor: #clockwise.
self should: [undoAction = #rotateCellCounterClockwiseAt:].
undoAction := ReverseLaserGameAction reverseActionSymbolFor: #counterClockwise.
self should: [undoAction = #rotateCellClockwiseAt:].
We don't expect this to pass just yet but it does help us to see where we want to go with our undo design implementation.
Back to the decision hierarchy we created. Add the following two class methods to the ReversePushCellEastLaserGameAction class.
actionSymbol
^#east
reverseActionSymbol
^#pushCellWestFromLocation:
Add these class methods to the ReversePushCellNorthLaserGameAction class.
actionSymbol
^#north
reverseActionSymbol
^#pushCellSouthFromLocation:
Add these class methods to ReversePushCellSouthLaserGameAction.
actionSymbol
^#south
reverseActionSymbol
^#pushCellNorthFromLocation:
Add these class methods to ReversePushCellWestLaserGameAction.
actionSymbol
^#west
reverseActionSymbol
^#pushCellEastFromLocation:
ReverseRotateClockwiseLaserGameAction
actionSymbol
^#clockwise
reverseActionSymbol
^#rotateCellCounterClockwiseAt:
ReverseRotateCounterClockwiseLaserGameAction
actionSymbol
^#counterClockwise
reverseActionSymbol
^#rotateCellClockwiseAt: