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:
  1. Create the .zip file for submission
  2. Make a new, empty directory
  3. Copy the submission file to the new directory
  4. Extract (unzip) all the files from your submission file into the new directory
  5. Verify that you can compile and run the program on your test cases in the new directory
  6. Go to the submissions page
  7. 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)
  8. 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).

Home
September 20, 2004