Ensure you have sbt
setup then run the following from the project root.
sbt run
The coordinate system starts at 1 for the x
and y
axis, starting in the top left corner of the canvas. So Coordinate(1, 1)
is the first drawable position (it correlates to the Java convention of (0, 0)
).
I was in two minds about using exceptions. I started by preventing an invalid coordinate being created by throwing an exception but switched to just ignoring out of range coordinates when applied to the canvas. I decided that "coordinates are coordinates"; even (-34, -23) is a "valid" coordinate. It's only when we apply them to the canvas that we have enough context to work out if they are really valid.
I used sub-types of Drawable
(originally Shape
) to represent lines and rectangles that can draw themselves. The rectangle implementation was fairly quick as it builds the rectangle in terms of four lines which are applied to the canvas in turn. It got me thinking about what would happen if any one of the four failed for some reason.
This lack of atomicity made me think about using a more immutable style canvas where potential updates (like applying a shape to a canvas) result in Either
an update or nothing. You could then replace the entire (old) canvas with a newly updated one on success.
Full disclosure: I don't have 100% test coverage. I don't think I need it. Some bits (notably the CommandLine
class) are not tested with automated tests. This is partly because I wasn't test driving at this point (I'd already settled on a design) and partly because finer grained testing was done elsewhere. I'm happy to discuss in more depth.
For fun, I integrated the code to work with a Raspberry Pi fitted with an 8x8 LED matrix. Because the Pi requires sudo
access to write to the GPIO pins, you have to run sbt
with privileges to see the blinky lights. Follow these steps.
git checkout raspberry_pi
sudo sbt run
Colour selection is as follows;
- Borders are red
- Lines and rectangles are blue
- Bucket fill uses a colour code;
g
is green,y
is yellow and so on. An unknown colour code defaults to magenta