CS 226: Data Structures, Program #2
Turtle Draw
Assigned: Monday, September 20, 2004
Due: Monday, September 27, 2004, 11:59 pm
(UNGRADED)
(Reminder: Please do not look at each
other's source code except for any designated project partner. For the
graded Project
#1 which builds on this program, we will be actively looking for
programs
that are "too similar", and I do not wish to find any.)
Overview
This program is the second component of the Turtle
Commander project. In this program, you will bring up a window
using AWT/Swing
and implement most of the turtle commands to draw lines into this
window.
Command Descriptions
In program 1, you parsed the turtle command language, and in this
program,
you will implement many of the commands. Following is a description of
the
desired function of the commands for this assignment. For this
assignment,
you will not be implementing push, pop, undo, or redo.
turn <clockwise_degrees>
The turtle should begin pointing horizontally towards the right.
Subsequent
turn commands should adjust the turtle's orientation. Positive degrees
turn
the turtle to the right (clockwise), whereas negative degrees turn the
turtle
to the left (counter-clockwise).
move <distance>
The move command causes the turtle to walk forward by <distance>
units.
Distance must be a positive number. If the pen is down, this movement
should
draw a line from the turtle's current position to the turtle's new
position.
If the pen is up, the turtle moves without drawing. The turtle's
initial position
is at the (0,0), which is the upper-left corner of the drawing area.
pen <up|down>
The pen command raises or lowers the virtual pen. When the pen is down,
issuing
a move command will draw a line. Otherwise, no line is drawn. The pen
should
begin in the down position.
color <red> <green> <blue>
The color command sets the current pen color. Lines drawn as a result
of the
move command should be drawn in the current pen color. The initial pen
color
should be black.
display
The display command should paint the picture generated by all the
commands
so far into the drawing window.
autodisplay <on|off>
When autodisplay is enabled, the picture seen in the drawing window
should
be kept up to date all the time. So, for example, you would need to
display
the picture after every line you draw. When autodisplay is disabled,
the recent
commands will only appear in the window after a display command (or a
window
event causing a refresh, such as uncovering a covered window). Turning
off
autodisplay can speed up the execution of long sequences of drawing
commands,
and it also allows you to control which intermediate states of the
drawing
the user will see.
exit
The exit command should exit the application and close the drawing
window.
To force awt to actually destroy the window, you may need to resort to
calling
something like System.exit( ) to accomplish this. You should also allow
your
application to exit as a result of clicking the window's close button.
Your
program should NOT exit when it parses an end-of-file (EOF) token. This
generally
occurs when you redirect a text file to the standard input of your
program
and the file reaches the end. If the program exits at this point, you
(and
the graders) will not have a chance to inspect the image.
Classes
You should implement several classes to build your program:
TurtleCanvas,
TurtleState, and TurtleCommander. In addition, you should have a class
hierarchy
that implements the TurtleCommand interface and possibly a TurtleTongue
class.
TurtleState
The TurtleState class stores the current information about the turtle.
This
includes its position in the drawing area, its orientation, its color,
its
pen state, and its autodisplay state.
TurtleCanvas
The TurtleCanvas class should inherit from one of the AWT
or Swing
classes to allow you to draw things inside a window. The is generally
accomplished
by defining a new class which extends an AWT/Swing class, such as
Component.
In this new class, you override the paint( ) function, allowing your
application
to control how the associated screen area is updated by the AWT thread
when
window events such as restore (from minimzed state) or expose (move a
window
in front of a covering window). You can also call this paint( )
function yourself
when you wish to update the display.
For this program, you will actually be drawing into an offscreen buffer
image (an instance of Jave2D's Image class..
So in the paint( ) function, you will just need to copy this image into
the
Graphics class of the TurtleCanvas. In this way, you do not have to
re-execute
all of your line drawing commands each time the window is repainted.
The offscreen
image retains all the drawn pixels from the lines you have previously
drawn.
(Note: a typical AWT/Swing application will have to re-issue all of its
drawing
commands directly into the on-screen Graphics instance each time the
window
needs to be updated, but this approach can speed things up for large
command
sets and avoids the need to store all the commands issued).
So, for example, your class's paint( ) function might look something
like
this:
public void paint(Graphics g) {
if (offscreen == null)
offscreen = createImage(getSize().width, getSize().height);
g.drawImage(offscreen, 0, 0, null);
}
When you draw lines, then they should go into offscreen.getGraphics( ).
TurtleCommander
The TurtleCommander class should contain your main( ) method, and it
should
have class instances of your TurtleState and TurtleCanvas class. If
your TurtleTongue
class contains useful methods that help you parse commands, you can
also
instantiate a TurtleTongue class and store it as a field of
TurtleCommander
as well. The static main( ) routine should instantiate a
TurtleCommander,
which should create and initialize a window and instantiate all its
class
fields. It then begins parsing commands, as you did in Program #1, but
instead
of printing the commands, it will apply them.
Creating and initializing a window might look something like this:
JFrame win = new JFrame();
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setSize(512,512);
win.setBackground(Color.white);
Container c = win.getContentPane();
c.add(turtleCanvas);
win.setVisible(true);
As in the above example code, your window should be created at a size
of 512x512.
Do not worry about handling window resize events in your application.
You
do not have to deal with issues like re-issuing all your drawing
commands
because the window was enlarged by the user.
TurtleCommand interface
Each of your command classes should implement the TurtleCommand
interface:
interface TurtleCommand {
public void print();
public void apply(TurtleCommander turtle);
}
As in the Program #1, you may find it helpful to have an abstract class
from
which to derive all of your individual command classes.
The apply( ) method should basically do whatever is required for the
command
in question. So it may draw things into the offscreen image, update the
TurtleState,
redisplay the image into the window, etc.
Create Some Cool Drawings
Once you have implemented the command set, start making some drawings!
Be
sure to test the command set thoroughly. Remember, in addition to
interactively
typing commands, you can redirect the commands from a test file (as
described
in Program #1). Unfortunately, it will currently be too difficult to
combine
the two in a single execution of your program. But you can experiment
interactively
with the program, then type all the commands you want to keep into a
text
file. You can repeat commands nicely in that framework using cut and
paste,
etc. Submit some of your test cases in text files, and note in the
README
what each one shows. Also submit one or more of your most creative
drawings
as command sets (please don't include captured image files, which could
take lots
of storage space).
I have posted a sample command file and the
corresponding
sample image for you to play around
with.
Restrictions
You may use the java.io, java.lang, java.awt,
and javax.swing class libraries. In general, you may not use
classes
from the java.util library unless you receive permission to do so for
some
particular class. Standard exceptions to this rule are StringTokenizer
and Random (which may be useful for testing some of your programs and
does
not jeopardize the goals of the class).
Submission - Read
this
Carefully
Your submission should include a set of .java
files, a README.txt file with any information you want to tell the
grader
about running your program (even though this one is ungraded), and some
text
files with your best test cases and pictures. If you are working with a
designated
project partner, you should specify
the submission ids of the two team members
(you only need to submit the program under a single person's submission
id).
Your main program class should be called TurtleCommander, and it should
be
compilable using "javac *.java" and runnable with the command "java
TurtleCommander".
You should submit your program as a single .zip (zip archive) file.
This
file should have no directory structure in it -- just the actual files,
so
extracting them should result in all your original files placed in the
current
directory.
To submit, you should follow these steps:
- Create the .zip file for submission
- Make a new, empty directory
- Copy the submission file to the new directory
- Extract (unzip) all the files from your submission
file into the new directory
- Verify that you can compile and run the
program on your test cases in the new directory
- Go to the submissions page
- Submit the .zip file, making sure that
the file appears in the directory listing displayed in the browser
after
submission (the file size listed could be slightly different on the
recipient
SunOS machine from that of a Windows OS machine, but they should
be
very similar)
- Also in the submissions page, View the
submission to be certain that the file is there (you should see
basically
the same directory listing you saw at the end of step 7).
If anything goes wrong with steps 7 or 8, try repeating them
(resubmitting
your file overwrites any previous submission and time stamp). If you
cannot
successfully submit your assignment, immediately send e-mail to the
professor
and the head TA explaining the problem (with all details so we can
hopefully
fix it) and including the submission file as an e-mail (MIME)
attachment. It is your responsibility to verify that the assignment
is
received. If we do not have an assignment or record of its submission,
it
will receive zero points.
Grading
Although this 2nd program is still not
graded, the complete multipart project will eventually be graded based
on
the following general criteria:
Compiling and running
Proper execution on a number of our test cases (with valid and invalid
inputs)
Overall implementation correctness
Comments, style, and readability (informative, but not extraneous
comments
are appreciated)
Effort/creativity of created pictures
If a project does not compile, you can expect to receive very few
points,
if any. This should encourage you to take care in your submission
process.
Final Words of Encouragement
Good luck with this assignment! I hope
you will have fun. You will probably find this assignment to be
significantly
longer than the first program, which was more of a warm-up. Although it
is
ungraded, we hope you will take it seriously and submit it on time. The
third,
GRADED, project will be due the week after this deadline, so avoid
getting
behind. Remember, if you have problems understanding the assignment or
how
to carry it out, please contact the TA, CA, or the professor, who are
there to help you. We
want to help all of you succeed, and are available by e-mail as well as
office
hours and appointments (if none of the office hours work for you).
September 20, 2004