TEACH TURTLE                                        Updated A.Sloman Sept 1986

                THE POP11 TURTLE
                ================

CONTENTS OF THIS FILE
    - (Put cursor at desired entry, use '<ENTER> g' to access sections)

 -- INTRODUCTON
 -- MAKING THE TURTLE FACE IN DIFFERENT DIRECTIONS
 -- DEFINING A PROCEDURE
 -- BIGGER PICTURES
 -- CHANGING THE "PAINT" USED BY THE TURTLE
 -- USING DRAWTO
 -- USING TURNTO
 -- JUMPBY AND DRAWBY
 -- EXAMINING THE PICTURE

-- INTRODUCTON --------------------------------------------------

This file introduces the POP-11 'turtle' library package, which enables
you to draw pictures on a rectangular grid, using the procedures DRAW,
JUMP, TURN, DRAWTO, JUMPTO, and more.

This program simulates a turtle crawling around a rectangular picture,
leaving a trail of paint. The picture can be printed on your terminal.
Leave TEACH by pressing the ENTER key, then type X then press RETURN.
Then, when you get the colon prompt from POP11, type the following to
get the program ready:

        turtle();
        newpicture(10,10);

The first command gets the turtle ready. The second, makes it use a
small enough picture to leave space on the screen for typing, etc. Type
TEACH; afterwards, to get back here.

Initially, you are provided with a (small) blank picture hidden in
the computer. If you type:
        display();

you'll get the blank picture printed out. Leave VED (ENTER-X-RETURN) and
try it. Type TEACH; to get back here.

The "T" tells you where the turtle is imagined to be: i.e. in the bottom
left of the picture, position 1.00 along and 1.00 up.

The picture is made up of a rectangular grid of square locations. This
is a representation of part of it. Notice that we count rows from the
bottom up, and rows and columns start from 1. The lines surrounding the
boxes are not drawn when you give the DISPLAY(); command.

   5-------------------------
    |   |   |   |   |   |   |
   4-------------------------
    |   |   |   |   |   |   |
   3-------------------------
    |   |   |   |   |   |   |
   2-------------------------
    | T |   |   |   |   |   |
   1-------------------------
    1   2   3   4   5   6   7

Initially, the turtle is ready to draw to your right, i.e.
(heading is "east"). Now leave VED and try:
         draw(4);
         display();

You'll see that the turtle has moved along in a horizontal direction
(heading "east") leaving a trail of asterisks.

The numbers printed alongside the picture are to help you count along
and up. The "T" shows you that the turtle has moved.

The draw command draws in the direction  of the current heading. The
TURN procedure can be used to change the heading. Turn (90) makes the
heading swivel through 90 degrees ANTI-clockwise (i.e. it will then face
NORTH, or up the screen). Go back to POP11 and try:

        turn(90);
        draw(3);
        display();


try:
        turn( -90 ); draw(5);
        display();

The picture can be thought of as made up of lots of imaginary squares.
The turtle starts off in the middle of the bottom left square. After
moving 7 units to the right, its position is (8, 1)

Try the following:
        jumpto(1,5);
        draw(5);
        display();

The JUMPTO command put the turtle on the left of the picture, five rows
up. It was still facing to your right (heading 0). the DRAW command told
it to move a distance of five units, leaving a trail. Jumpto some other
location, e.g. 2 along and 3 up, then display the picture. You may do
this several times, if you wish, with different picture locations.

The picture initially created by the NEWPICTURE(10,10); command, above
is 10 units wide and 10 units high. To check this type:
        picture =>

If you draw beyond the edge of the picture, you'll get a 'mishap'
message.
Try the following sequence:
        turtle();
        draw(99);

You can now use DISPLAY, as before, to see how far the turtle got:
        display();
Then:
        xposition, yposition =>
Compare the line starting "involving" in the mishap message.

The mishap occurred because the turtle was trying to "paint" an
asterisk at a non-existent picture location. Further DRAW commands
will again produce an error, since the turtle is at the edge of the
picture, and facing off it. E.g. try:
        draw(2);

But you can make the turtle turn and draw in another direction:
        turn(90);
        draw(5);
        display();

You can restart with the TURTLE(); command, to get a clean picture.
        turtle();
        draw(7); display();

You can also use JUMP, to move the turtle in its current heading,
e.g.
    turtle(); draw(5); turn(90);
    jump(3); draw(5);
    display();

You can jump either forwards or backwards, e.g. JUMP(3); JUMP(-3);
Try drawing something using DRAW, TURN, JUMP, and DISPLAY.
Can you draw a capital H ?

If you've had enough for now, type ENTER-Q to abandon this TEACH
file, then leave POP11.
You can come back later and continue from this place if you note the line
number in the status line, above. To jump to line 150, say, you can do
    teach turtle;

then
    press ENTER, then type @150 (i.e. at location 150) then press RETURN.

go back to POP11 and try that now, for practice.

If you leave POP11 now and come back later, you'll have to type
    turtle();

to get the turtle ready again. The default picture size is 20 by 20. To
get a smaller picture, to leave more space on the screen, do
    newpicture(20,10);

This will make a picture which is 20 along and 10 up. You can experiment
with different sizes.



-- MAKING THE TURTLE FACE IN DIFFERENT DIRECTIONS ---------------

The TURN command alters the way the turtle is facing.
 Try the following:
        newpicture(15,15);
        draw(5);
        display();
        newpicture(15,15);

The NEWPICTURE command creates a new picture of a different size.
Now type:
        heading =>
        turn(90);
        heading =>
        draw(5);
        display();
Notice how position and heading change.

The TURN(90) command said to the turtle: "turn left (counterclockwise)
by 90 degrees". So having previously been facing to the right, it is
now facing up (north).
Turns like this alter the value of the variable "HEADING".
Try:
        turn(90);
        heading =>
        turn(-90);
        heading =>
        turn(45); heading =>

The TURN command does not affect the position, only the heading.
TURN applied to a negative number (e.g. -90 ) means "turn clockwise".
(e.g. it is equivalent to "turn right".)
Try the following, and see if you can guess what will happen:
        turtle();
        draw(5); turn(90); draw(5);
        display();
        turn(135);
        draw(7);
        display();

Notice that although the last command said "draw over a distance of
7 units," it did not produce 7 asterisks. This is because all the
asterisks have to be lined up with rows of printing. You'll always
find that when the turtle is drawing in a direction other than
vertical or horizontal it doesn't produce exactly as many asterisks
as the distance drawn.
You'll also find that if you draw in other directions than the
horizontal vertical or diagonal, the lines look very strange.
try
        turtle(); turn(20); draw(9); display();
        turtle(); turn(60); draw(10); display();

The TURTNASTY demo explains in more detail. For now it is simplest to
stick to horizontal, vertical and diagonal lines. Give the TURTLE();
command to get a new picture, then draw some pictures, using DRAW, TURN,
JUMP, DISPLAY. If you want a bigger picture again, use NEWPICTURE, e.g.
NEWPICTURE(30,20) gets you a picture 30 characters wide and 20 high.

If mishaps arise which you cannot understand, ask for help.

When you want to find out where the turtle is and which way it is
facing without giving a DISPLAY(); command, you can do this:
        xposition, yposition, heading =>
Try it.


-- DEFINING A PROCEDURE -----------------------------------------

You may get tired of typing XPOSITION, YPOSITION, HEADING => every time
you want the turtle to print out its current state. So you can define a
procedure called WHERE which will do it all for you.

        define where();
                [^xposition, ^yposition, ^heading] =>
        enddefine;

Type that, including the funny arrows.
If you have learnt to use the editor, use it to put this in a file.
It will save a lot of time if you make typing mistakes.


Check that the procedure WHERE has been defined:
        where =>

If the computer does not print out
        ** procedure<where>
try typing in the definition of the procedure again.
If you are not used to procedures, try TEACH DEFINE some time.


You can execute the procedure just defined, by typing:
        where();
        jumpto(4,7);
        where();

The procedure makes a three element list, using the "up arrow" ^ to
include the VALUES of three variables, and prints out the list.

If you keep forgetting which way TURN works, you may find it useful
to define procedures called LEFT and RIGHT. If you put them on
files they will be available for future use (using LOAD).
Try:
        define left(angle);
                turn(angle);
        enddefine;

        define right(angle);
                turn( -angle);
        enddefine;

        heading =>
        left(90); heading =>
        right(45); heading =>
        right(45); heading =>

Then test the procedures:
        turtle();
        draw(3); display();
        left(90); draw(3); display();
        right(45); draw(5); display();
        right(135); draw(5); display();

Use these to create a procedure to draw a "T".
        define tee(size);
                jump(size/2);
                turn(90);
                draw(size);
                turn(90);
                draw(size/2);
                turn(180);
                draw(size);
                display();
        enddefine;

then test it:
        turtle();
        tee(5);
        turtle();
        tee(8);

If you wish to abbreviate DISPLAY, you can declare a new variable
and assign DISPLAY to it, thus:
        vars dis;
        display -> dis;
        dis();
After that you can use DIS instead of DISPLAY.

Try defining a procedure called CORNER, which makes the turtle DRAW(5);
then TURN(90); then DRAW(5); then DISPLAY();

        define corner();
                < you fill in this bit >
        enddefine;
try it then test the procedure by typing:
        corner();

Your procedure could have been:
        define corner();
                draw(5);  turn(90); draw(5);
                display();
        enddefine;

Try that if your definition did not work. Then try:
        turtle();
        corner();
        corner();
Could you define a procedure to draw a square?

-- BIGGER PICTURES ----------------------------------------------

You can use the NEWPICTURE command to produce a bigger picture
e.g. to get a picture 30 characters wide and 16 high type:
        newpicture(30,16);
The turtle is always put at the bottom left, facing right, by NEWPICTURE.
Check this:
        display();
        xposition, yposition, heading =>

Try drawing a rectangle, 15 units wide and 10 high, then display it.

E.g. you could have done something like:
        newpicture(18,18);
        repeat 2 times
              draw(15); turn(90); draw(10); turn(90);
        endrepeat;
        display();

The bit between "times" and "endrepeat" is obeyed the number of
times specified by the number after "repeat", i.e. twice.
Try drawing a rectangle of a different size, using a REPEAT command.
Then DISPLAY it.

Can you use REPEAT to draw a 5 by 5 square?
Try it.

If you didn't manage, try something like:
        turtle();
        repeat 4 times draw(5); turn(90); endrepeat;
        display();
Try a bigger square, e.g. 15 by 15.

One thing we can't help is the fact that
teletypes stretch squares vertically because they type with
bigger spaces between rows than between characters in rows.
Can you predict what happens if you reverse the TURN and DRAW
commands, thus:
        turtle();
        repeat 4 times turn(90); draw(15); endrepeat;
try it.

This is what happened when the repeat command was obeyed.
It tries to do TURN(90); then DRAW(5) four times.
The turtle starts off facing to the right, so the first
TURN(90) makes it face up (North: heading = 90).
The first DRAW(5) takes it up the left of the picture.
The next TURN makes it face to the left (WEST: heading = 270),
i.e. facing off the edge of the picture,
and the following DRAW causes a mishap.
Type DISPLAY(); and make sure you understand what happened.


-- CHANGING THE "PAINT" USED BY THE TURTLE ----------------------

To make sure the picture is clear, type:
        turtle();
You may wish to make the turtle leave a different sort of trail when
it draws. You can do this by changing the "paint". E.g. if you wish
to make it leave a trail of dots instead of asterisks do:
        "." -> paint;

i.e. assign the word "." to be the value of the variable PAINT.
Try it then draw something and display the picture.

Now clear the picture, e.g. NEWPICTURE(15,15); and try to
draw a square of side ten units long (using whatever paint you like).
Try it then display the picture.

The following should have worked:
        turtle();
        "." -> paint;
        repeat 4 times
                draw(10);
                turn(90);
        endrepeat;

Try that, followed by DISPLAY(); if yours didn't work.
Can you guess how to make the turtle leave a trail of
plus signs "+" for its paint?


Change the paint thus:
        "+" -> paint;
Then draw something, and display it.

It is a bit tiresome having to type in the whole REPEAT instruction
every time you want to draw a square. To avoid doing so, you can define
a new procedure called SQUARE, thus:

        define square(size);
                repeat 4 times
                        draw(size); turn(90);
                endrepeat;
        enddefine;

This tells the computer to store a procedure called SQUARE which is to
be executed with input, or "argument", temporarily named SIZE. When the
procedure is executed, it will make the turtle draw and turn four times,
the distance drawn depending on the value of SIZE.

Make a new picture about 20 by 20.
Then use the procedure SQUARE to draw a few squares, thus:

        square(15);
        display();
        square(10);
        square(5);
        display();

Notice how the turtle always returns to the same place and heading
after executing SQUARE. If you can't see why ask for help.

SQUARE(15); means, roughly "obey the instructions in the definition of
procedure SQUARE, with 15 as the value for the variable SIZE".
Now try this:
        newpicture(20,20);
        1 ->paint;      ;;; prepare to leave a train of 1s
        jumpto(6,6);
        square(8);
        display();

        2 ->paint;
        jumpto(2,2); square(16);
        where(); display();

        jumpto(10,4);
        3 -> paint;
        turn(45); square(8);
        display(); where();

Notice that JUMPTO, unlike DRAW, requires two inputs, i.e. two numbers
representing the desired XPOSITION and the YPOSITION of the location.
JUMPTO does not alter the value of HEADING.

-- USING DRAWTO -------------------------------------------------

Clear the picture:
        turtle();

Then draw a square:

        repeat 4 times
                draw(14); turn(90);
        endrepeat;
        display();

How could you draw a diagonal line across a square? You could try to
TURN(45); then use DRAW. But you'd have to calculate the distance.
Instead you can use the procedure DRAWTO.
try:
        turtle();
        drawto(15,15); display();

Try the following:
        true -> changepaint;            ;;; prepare to alter paint.
        newpicture(20,20);
        "a" -> paint;
        drawto(15,1); drawto(15,15);
        drawto(5,15); drawto(5,5);
        drawto(10,5); drawto(10,10);
        display();

To avoid so much typing to draw that you can use a REPEAT instruction.
        newpicture(20,20);
        vars dist;              ;;; declare a new variable
        15 -> dist;             ;;; assign 15 to be its value

        repeat 4 times
            draw(dist); turn(90);
            draw(dist); turn(90);
            dist - 3 -> dist;
        endrepeat;
        display();

try that, without the comments following ";;;".

The line before ENDREPEAT says: subtract 3 from DIST and assign the
result to be the new value of DIST. The whole REPEAT instruction, which
starts with REPEAT and ends with ENDREPEAT, says "do everything between
TIMES and ENDREPEAT four times".

If you now want to draw a different squiral it will be rather tedious to
have to retype all that. So define a procedure:

        define squiral(num, dist, sub);
           repeat num times
                draw(dist);
                turn(90);
                dist - sub -> dist;
           endrepeat;
        enddefine;

If you've learnt how, use the editor to store this definition in
a file for future use.
This defines a procedure called SQUIRAL which will have to be given
three arguments, to be called NUM DIST and SUB, when it is
executed.

Create a new picture and try executing it thus:
        turtle();
        squiral(15, 17, 1);
        display();

This says, run SQUIRAL with 15 as the value for NUM, 17 as the value
for DIST and 1 as the value for SUB, the amount to be subtracted each
time. Try running SQUIRAL with different values, e.g.
        squiral(12,20,1);

You could redefine SQUIRAL so that the DISPLAY command is
included between ENDREPEAT and ENDDEFINE.

What will the following do:
        squiral(5,5,2);

This is what happened:
If you subtract 2 from 5 more than twice you end up with
a negative number. So DIST will become negative. That's alright:
drawing a negative amount just means drawing backwards. Similarly,
JUMP(-3); means "jump 3 backwards".
Try to work out what the following will do, then do it.
        newpicture(20,20);
        jumpto(10,10);
        repeat 8 times draw(6); jump(-6); turn(45) endrepeat;
        display();

It should have made a star. If not, try again.
Try to make a star of a different size, or a star using a different
paint, e.g. ".", or "+", or "o".

-- USING TURNTO -------------------------------------------------

Try the following:

        newpicture(10,10);
        jumpto(2,2);
        drawto(6,6);
        draw(3); display();

Notice that the DRAWTO command drew a line, but did not make the turtle
face along that line. So the DRAW command used the original heading.

The procedure TURNTO is available to make the turtle face in the
direction of a specified point. TURNTO(X,Y) makes it face in the
direction of the point with co-ordinates X,Y.
Try the following, or some variation of it:

        newpicture(21,21);
        jumpto(11,11); turnto(21,1); draw(5);
        jumpto(11,11); turnto(11,1); draw(5);
        jumpto(11,11); turnto(21,1); draw(5);
        jumpto(11,11); turnto(21,21); draw(5);
        display();

You can't make the turtle TURNTO the point its already on. Try:
        jumpto(1,1); turnto(1,1);

-- JUMPBY AND DRAWBY --------------------------------------------


See if you can guess what the following will do, then try it:

        newpicture(30,25);
        1 -> paint;
        repeat 5 times
            draw(3);
            jumpby(2,2);
            paint + 1 -> paint;
        endrepeat;
        display();

JUMPBY(X,Y) means, "without leaving a trail, move X units
to the right and Y units up". To move to the left, or down,
you can use negative numbers, e.g. JUMPBY(-5, 0); to move left.
Try the last lot again using DRAWBY instead of JUMPBY.
The only difference is that DRAWBY leaves a trail of paint.
Both require two arguments (inputs), like DRAWTO and JUMPTO,
but the arguments are not taken to be co-ordinates of a point.

-- EXAMINING THE PICTURE ----------------------------------------

Draw a little picture:
        newpicture(15,15);
        square(10);

If you don't have a procedure SQUARE, use REPEAT instead.

The picture inside the machine is really an "array" called "PICTURE".
You can examine its contents without using DISPLAY to print it all out.
For instance to find out what is at the location (1,3), type:
        picture(1,3) =>

This prints out two asterisks, followed by the paint at location (1,3).
The paint may be blank, at the location, i.e. if it contains a space.
Try this:
        "*" =>
        "+" -> paint;
        paint =>
        space =>

"SPACE" is a special POP11 variable, whose value is a word containing
a space. You cannot type in such a word yourself. Try:
        " " =>

Some picture locations have a space, whilst others have the word
corresponding to the paint used. You can look at several locations,
thus:

        picture(3,1) =>
        picture(3,3) =>
        picture(1,3), picture(1,4), picture(2,4) =>
        display();

If you want to know what is at the current turtle location type:
        picture(xposition,yposition) =>

This is a bit much to have to type each time, so you can define a
procedure called COLHERE thus:

        define colhere;
         picture(xposition, yposition) =>
        enddefine;

        colhere();
        jump(1);
        colhere();
        jumpby(2,2);
        colhere();
        xposition, yposition =>

Try this:
        turtle();
        jumpto(2,1);
        square(5);
        jumpto(1,1); 0 -> heading;
        repeat 8 times
            colhere();
            jump(1);
        endrepeat;

This prints out what is at 8 locations in a straight line
starting at (1,1) and going to the right.

Using procedures like COLHERE you can make the turtle move about the
picture examining its contents and perhaps trying to recognise or
interpret what has been drawn. What would it require in order to be able
to recognise squares, as well as draw them? Don't try to answer now.

HELP TURTLESUM gives a summary of turtle procedures.

TEACH SEEPICTURE introduces further uses of the turtle.

TEACH VTURTLE shows how to use a VED editor window as the picture into
which the turtle draws. This presupposes familiarity with VED and the
use of marked ranges in VED.

See TEACH TEACHFILES for a more comprehensive list of available POP-11
TEACH files

-----<Copyright University of Sussex 1986.  All rights reserved.>-------
