Programming Assignment 3 - Turtle Graphics

Advanced Programming II, Spring 2002


Due Date

This assignment is due by 2:00 p.m. on Thursday, 5 March.

See the assignment turn-in page (last modified on 22 January 2002) for instructions on turning in your assignment.

Background

The turtle is a device that crawls around on a piece of paper. The turtle has a pen, which, if it's contact with the paper while the turtle moves, draws on the paper. The turtle has a head; when the turtle moves forward, it moves in the direction pointed to by its head.

a turtle

The turtle crawls around according to the following commands:

  1. F - move forward f units with the pen on the paper.

  2. f - move forward f units with the pen off the paper.

  3. + - rotate the turtle r degrees clockwise (to the right) about the pen.

  4. - - rotate the turtle l degrees counterclockwise (to the left) about the pen.

The turtle's position is the (x, y) location of its pen and the direction its head is pointing. The turtle also has a position stack which it uses to remember positions; the position stack has infinite capacity. The turtle manipulates its position stack in response to two more commands:

  1. [ - push the current position into the position stack. This command does not change the turtle's position.

  2. ] - pop a position off the top of the state stack and set the turtle's position to be equal to the popped position. This command (usually) changes the turtle's position.

A sequence of turtle commands is known as a turtle string. Despite the suggestive names, it is not necessary for the [ and ] commands to match in a turtle string. However, the turtle should never try to pop an empty position stack. For example,

F [ F [ F

is a good turtle string even though the turtle never pops the position stack, while

F[F]]

is a bad turtle string because the turtle tries to pop the empty position stack (assuming the position stack was empty at the start of the string).

A turtle executes a turtle string by scanning the string from left to right and executing each command it finds. For example, when executed, the turtle string F + f - F causes the turtle to

move forward n units with the pen down
rotate clockwise r degrees
move forward n units with the pen up
rotate counter-clockwise r degrees
move forward n units with the pen down

The result of executing a turtle string is the drawing the turtle leaves behind. In the previous example, the result is

the result of executing turtle string F+f-F

(the commands and turtles are not part of the drawing).

A turtle program has the following format

turtle-strings
turtle-stringp -> turtle-stringr
drawing commands

A turtle program executes as follows:

  1. The start turtle string turtle-strings is evolved through some number of generations to produce the final turtle string.

  2. The turtle executes the final turtle string to produce a drawing.

A turtle string s is evolved from one generation to the next in the following way:

  1. Each non-overlapping occurrence of the pattern turtle string turtle-stringp is marked in a left-to-right scan of s.

  2. Each marked occurrence of turtle-stringp in s is replaced by the replacement turtle string turtle-stringr.

For example, given the turtle program

F + F + F
F + F -> F + F + [ F + F ]

the generation 0 turtle string is the start turtle string F + F + F. The generation 1 turtle string evolves from the generation 0 turtle string

F + F + F

by marking all non-overlapping occurrences of the pattern turtle string F+F from left to right:

F+F + F

and replacing the marked pattern turtle strings with the replacement turtle string F + F + [ F + F ]:

F+F+[F+F] + F

The generation 2 turtle string evolves from the the generation 1 turtle string

F + F + [ F + F ] + F

by marking all non-overlapping occurrences of the pattern turtle string F+F from left to right:

F+F + [ F+F ] + F

and replacing them with F + F + [ F + F ]:

F+F+[F+F] + [ F+F+[F+F] ] + F

and so on.

Drawing commands is a sequence of zero or more of the following commands:

  1. draw n - Create an n-th generation turtle string and execute it. n is an non-negative integer.

    At the start of each draw command the turtle is positioned with its pen at the origin of a Cartesian coordinate system (increasing x to the right, increasing y up) with its head pointing up the positive Y axis (that is, at 90 degrees).

  2. right = r - Sets the amount of clockwise rotation caused by a + command to r degrees. r is a floating point number; if r is less than zero, then the turtle rotates counter-clockwise.

  3. left = l - Sets the amount of counter-clockwise rotation caused by a - command to l degrees. l is a floating point number; if l is less than zero, then the turtle rotates clockwise.

  4. forward = f - Sets the number of units moved by a F or f to f units. f is a floating point number; if f is less than zero, then the turtle moves backward (that is in the direction opposite of forward).

The initial values are l = r = 20 degrees and f = 1 unit. Drawing commands may appear in any order. Each right, left, or forward command effects all subsequent draw commands until they are changed by a following right, left, or forward command. If a turtle program doesn't contain any draw commands, the program does nothing.

The Problem

Write a program that reads a turtle program from std-in and executes it.

Input

The input consists of a single turtle program as described in the Background section. If your program encounters a syntax or execution error anywhere in the program, it should print an informative error message to std-err and quit.

Each component of a turtle program (start string, pattern and replacement, or drawing command) occupies a single line of text, and a single line of text can contain at most one component of a turtle program.

Zero or more non-newline space characters can appear anywhere in a turtle program except within the words left, right, forward, draw, and ->. All non-newline space characters should be ignored.

Arbitrary numbers of blank lines (that is, lines containing only space characters) may appear between any two lines of a turtle program and should be ignored.

Output

Your program should output one PostScript file per draw command; the contents of the file is the turtle drawing that results from executing the program for the number of generations given in the draw command.

The files ps.h and ps.cc in /export/home/class/cs-509/pa3 contain routines to help your program create PostScript files; see ps.h for details. To compile a file including ps.h, use the command

g++ -c -I/export/home/class/cs-509/pa3 your-file.cc

You can use the gs or ghostview programs to view your PostScript files.

Testing

/export/home/class/cs-509/pa3 contains are several turtle programs and example drawings. The turtle program turtle-i.pgm produces the drawings turtle-i-genj.ps.


This page last modified on 26 February 2002.