Section 4

Communicate With Arrow Colors

We have a working LaserGame. There are a number of enhancements to consider. The first one I want to try is change the hint arrows so they show a move is restricted by using color. For the existing code we are painting grey arrows. What if we made the color of the arrows dependent on whether the choice was valid or not?

The first thing we would need to do is provide 2 arrow color methods in our LaserGameColors class. Write 2 new class methods that answer an appropriate color.

allowActionArrowColor
    ^Color green

denyActionArrowColor
    ^Color red

We can begin with those 2 primary colors (red and green). After we get things working we'll probably regret these color choices since they will likely look very bright and harsh over our game cells. But we'll worry about that later.

The next step is to figure out to use these new colors. We will need a way to check permission for the action the user could take. For the rotate action, it's easy. There's no restriction. For the push action we've already written the code that prohibits the actual push to take place. We need to figure out how to reuse that pattern for a new permission check.

Back on the Grid class we wrote an instance method that handled the push of a cell. It checked if the push was possible and if not it answered back the same cell. Otherwise it answered a cell for swapping in the push. Here's that method. We're not going to change it, just review it for what we would do if we were calculation permission to push instead.

pushCell: aGridDirection fromLocation: aPoint
    | cell vector swapLoc swapCell |
    cell := self at: aPoint.
    cell class = MirrorCell ifFalse: [^cell].
    vector := aGridDirection vector.
    swapLoc := aPoint + vector.
    swapCell := self at: swapLoc.
    swapCell isNil ifTrue: [^cell].
    swapCell class = BlankCell ifFalse: [^cell].
    self clearCellsInPath.
    self swapCell: cell with: swapCell.
    self laserIsActive ifTrue: [self activateCellsInPath].
    ^swapCell

Here is a new instance method that takes the same idea and calulates a Boolean (true/false) if the action can be validly performed.

canPushCell: aGridDirection fromLocation: aPoint
    | cell vector swapLoc swapCell |
    cell := self at: aPoint.
    cell class = MirrorCell ifFalse: [^false].
    vector := aGridDirection vector.
    swapLoc := aPoint + vector.
    swapCell := self at: swapLoc.
    swapCell isNil ifTrue: [^false].
    swapCell class = BlankCell ifFalse: [^false].
    ^true

There's probably some refactoring we can do in here but I'm going to press onward.

Index Page Next Page

Copyright © 2007, 2008, 2009, 2010 Stephan B Wessels    stevewessels@me.com