One thing I have often seen and lamented is students
writing excessively complicated code with way too many
classes.�� There is a huge difference between
�� "A Robot knows its position and direction."
and
�� "A Robot has-a Position and has-a Direction."
The first is the important one.�� The second is
an over-commitment to too many classses.�� For a
problem like this, you really really do not want
a Direction class, and you certainly have no use
for double dispatch.
A position can be represented by a pair of integers
x, y.�� It could also be represented by a Point with
integer components.
A direction could be represented by a pair of integers
dx, dy such that |dx|+|dy| = 1.�� It could also be
represented by a Point with integer components.
For movement, you need to be able to add the direction
to the location, which could be simply
x := x + dx.�� y := y + dy.
or it could be
position := position + direction.
For turning, you need to be able to rotate a direction
vector by ninety degrees.�� Now it so happens that
Point has methods #leftRotated and #rightRotated.
So we can do the following:
���� a Robot has position (a Point) and direction (aPoint)
���� position := 0 @ 0.
���� direction := 0 @ 1.
To move forward without turning:
���� position := position + direction.
To turn left without moving:
���� direction := direction leftRotated.
To turn right without moving:
���� direction := direction rightRotated.
To obey a sequence of characters, commands:
���� commands do: [:each |
���������� each caseOf: {
���������������� [$A] -> [--move forward--].
���������������� [$L] -> [--turn left--].
���������������� [$R] -> [--turn right--]
���������� }].
One of the key ideas in extreme programming is
"You Ain't Gonna Need It", abbreviated to YAGNI!
The idea is *DON'T* generalise beyond your immediate
needs.�� In this case, for example, the likelihood of
*this* program needing to deal with more general
kinds of movement is ZERO.�� And the only reason for
using Point here instead of just using a few simple
assignment statements is that Point already exists,
so costs nothing to write, and as a familiar class,
code using it should be easy to read.
If someone challenges you to do something counter-productive,
refuse the challenge.