The three rules of Ruby Quiz:
1. Please do not post any solutions or spoiler discussion for this quiz until
48 hours have passed from the time on this message.
2. Support Ruby Quiz by submitting ideas as often as you can:
http://www.rubyquiz.com/
3. Enjoy!
Suggestion: A [QUIZ] in the subject of emails about the problem helps everyone
on Ruby Talk follow the discussion. Please reply to the original quiz message,
if you can.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
by Morton Goldberg
[Editor's Note: You can download the files for this quiz at:
http://rubyquiz.com/turtle.zip
--JEG2]
Turtle Graphics
===============
Turtle graphics is a form of computer graphics based on the ideas of turtle
geometry, a formulation of local (coordinate-free) geometry. As a brief
introduction to turtle graphics, I quote from [1]:
Imagine that you have control of a little creature called a turtle
that exists in a mathematical plane or, better yet, on a computer
display screen. The turtle can respond to a few simple commands:
FORWARD moves the turtle in the direction it is facing some
number of units. RIGHT rotates it clockwise in its place some
number of degrees. BACK and LEFT cause the opposite movements. ...
The turtle can leave a trace of the places it has been: [its
movements] can cause lines to appear on the screen. This is
controlled by the commands PENUP and PENDOWN. When the pen is
down, the turtle draws lines.
For example, the turtle commands to draw a square, 100 units on a side, can be
written (in a Ruby-ized form) as:
pen_down
4.times { forward 100; right 90 }
For more information, see [2] and [3].
This quiz is a bit different from most. If the usual Ruby quiz can be likened to
an essay exam, this one is a fill-in-the-blanks test. I'm supplying you with a
complete turtle graphics package, except -- to give you something to do -- I've
removed the method bodies from the key file, lib/turtle.rb. Your job is to
repair the damage I've done and make the package work again.
Turtle Commands
===============
There are quite a few turtle commands, but that doesn't mean you have to write a
lot of code to solve this quiz. Most of the commands can be implemented in a
couple of lines. It took me a lot longer to write a description of the commands
than it did for me to implement and test all of them.
I use the following format to describe turtle commands:
long_name | short_name <arg>
description ...
Example: ...
All turtle commands take either one argument or none, and not all turtle
commands have both a long name and a short name.
Required Commands
-----------------
These commands are required in the sense that they are needed to reproduce the
sample designs. Actually, you could get away without implementing 'back' and
'left', but implementing them is far easier than trying to write turtle code
without them.
pen_up | pu
Raises the turtle's pen. The turtle doesn't draw (lay down a visible
track) when its pen is up.
pen_down | pd
Lowers the turtle's pen. The turtle draws (lays down a visible track)
when its pen is down.
forward | fd <distance>
Moves the turtle forwards in the direction it is facing.
Example: forward(100) advances the turtle by 100 steps.
back | bk <distance>
Moves the turtle backwards along its line of motion.
back <distance> == forward -<distance>
Example: back(100) backs up the turtle by 100 steps.
right | rt <angle>
Turns the turtle clockwise by <angle> degrees.
Example: right(90) turns the turtle clockwise by a right angle.
left | lt <angle>
Turns the turtle counterclockwise by <angle> degrees.
left <angle> == right -<angle>
Example: left(45) turns the turtle counterclockwise by 45 degrees.
Traditional Commands
--------------------
These commands are not needed to reproduce any of the sample designs, but they
are found in all implementations of turtle graphics that I know of.
home
Places the turtle at the origin, facing north, with its pen up. The
turtle does not draw when it goes home.
clear
Homes the turtle and empties out it's track. Sending a turtle a clear
message essentially reinitializes it.
xy
Reports the turtle's location.
Example: Suppose the turtle is 10 turtle steps north and 15 turtle steps
west of the origin, then xy will return [-15.0, 10.0].
set_xy | xy= <point>
Places the turtle at <point>. The turtle does not draw when this command
is executed, not even if its pen is down. Returns <point>.
Example: Suppose the turtle is at [10.0, 20.0], then self.xy = [50, 80]
moves the turtle to [50.0, 80.0], but no line will drawn between the [10,
20] and [50, 80].
heading
Reports the direction in which the turtle is facing. Heading is measured
in degrees, clockwise from north.
Example: Suppose the turtle is at the origin facing the point [100, 200],
then heading will return 26.565 (approximately).
heading= | set_h <angle>
Sets the turtle's heading to <angle>. <angle> should be given in degrees,
measured clockwise from north. Returns <angle>.
Example: After self.heading = 135 (or set_h(135) which is easier to
write), the turtle will be facing southeast.
pen_up? | pu?
Reports true if the turtle's pen is up and false otherwise.
pen_down? | pd?
Reports true if the turtle's pen is down and false otherwise.
Optional Commands
-----------------
These commands are only found in some implementations of turtle graphics. When
they are implemented, they make the turtle capable of doing global (coordinate)
geometry in addition to local (coordinate-free) geometry.
I used one of these commands, go, to draw the mandala design (see
designs/mandala.tiff and samples/mandala.rb). If you choose not to implement the
optional commands, you might try writing a turtle program for drawing the
mandala design without using go. But, believe me, it is much easier to implement
go than to write such a program.
go <point>
Moves the turtle to <point>.
Example: Suppose the turtle is home (at the origin facing north). After
go([100, 200]), the turtle will be located at [100.0, 200.0] but will
still be facing north. If its pen was down, it will have drawn a line
from [0, 0] to [100, 200].
toward | face <point>
Turns the turtle to face <point>.
Example: Suppose the turtle is at the origin. After toward([100, 200]),
its heading will be 26.565 (approximately).
distance | dist <point>
Reports the distance between the turtle and <point>.
Example: Suppose the turtle is at the origin, then distance([400, 300])
will return 500.0 (approximately).
Interfacing to the Turtle Graphics Viewer
=========================================
Implementing turtle graphics without being able to view what the turtle draws
isn't much fun, so I'm providing a simple turtle graphics viewer. To interface
with the viewer, turtle instances must respond to the message track by returning
an array which the viewer can use to generate a line drawing.
The viewer expects the array returned by track to take the following form:
track ::= [segment, segment, ...] # drawing data
segment ::= [point, point, ...] # points to be joined by line segments
point ::= [x, y] # pair of floats
Example: [[[0.0, 0.0], [200.0, 200.0]], [[200.0, 0.0], [0.0, 200.0]]]
This represents an X located in the upper-right quadrant of the viewer; i.e.,
two line segments, one running from the center of the viewer up to its
upper-right corner and the other running from the center of the top edge down to
the center of the right edge.
[Editor's Note: I added a script to dump your turtle graphics output to PPM
image files, for those that don't have TK up and running. It works identically
to Morton's turtle_viewer.rb, save that it writes output to a PPM image file in
the current directory. For example, to output the included tree image, use
`ruby turtle_ppm_writer.rb samples/tree.rb`. --JEG2]
Unit Tests
==========
I'm including the unit tests which I developed to test turtle commands. For the
purposes of the quiz, you can ignore tests/turtle_view_test.rb. But I hope you
will find the other test suite, tests/turtle_test.rb, helpful. It tests every
one of the turtle commands described above as well as argument checking by the
commands. Don't hesitate to modify any of the unit tests to meet the needs of
your quiz solution.
References
==========
[1] Abelson, H. & A. diSessa, "Turtle Geometry", MIT Press, 1981.
[2] Harvey, B., "Computer Science Logo Style", Chapter 10.
http://www.cs.berkeley.edu/~bh/pdf/v1ch10.pdf
[3] Wikipedia,
http://en.wikipedia.org/wiki/LOGO_programming_language