Writing with the Turtle, part 3

Here below is code similar to the code of part 2 but extended to include sequences for every capital letter A-Z, every digit 0-9, as well as the space and hyphen characters. This program waits for you to type a character which the turtle then draws for you. When the turtle has finished drawing (and there is code to check that it really has finished) then you can try another character. The way the program detects that a key has been pressed while the graphics window is active is by using this command: 

GraphicsWindow.TextInput = OnTextInput

That code tells the program that if a key is pressed then the subprogram 'OnTextInput' should be called. The character corresponding to the pressed key is stored in GraphicsWindow.LastText ready to be used by the program.

If you don't like the way I've designed certain characters then feel free to modify the code - it's a great way to learn! Note that the sequences below do not include the '10' pair that you have seen at the end of every sequence previously - this pair corresponds to the space between characters which is not relevant to this program.

GraphicsWindow.Width=500

GraphicsWindow.Height=500

GraphicsWindow.PenWidth=4

Turtle.Speed=7

Turtle.PenUp()

GraphicsWindow.penColor="yellow"

For y=50 To 450 Step 200  'draw horizontal grid lines

  GraphicsWindow.DrawLine(150,y,350,y)

EndFor

For x=150 To 350 Step 100  'draw vertical grid lines

  GraphicsWindow.DrawLine(x,50,x,450)

EndFor

GraphicsWindow.TextInput = OnTextInput 'Call the OnTextInput

'subprogram if a key press is detected

GraphicsWindow.Title="Type a character"

GraphicsWindow.penColor="black" 

busy="False"

Sub OntextInput

  If busy="False" then

    busy="True"  'Don't allow another drawing

                 'to begin until this one is complete

    For i = 1 To 10000  'bug workaround - see below

      Shapes.Remove("_turtleLine"+i)

    EndFor

    char = GraphicsWindow.LastText ' get the character entered

    Turtle.x=150

    Turtle.y=450

    Turtle.Angle=90   'point right

    

    sequence[0]= "1P Qq 20 Qr 20 Qq 0p 10"

    sequence[1]= "0A 30 0c 0P cc 0a 4p 0A 5P 2p"

    sequence[2]= "0A 3P qs Qq 1A 2p"

    sequence[3]= "0P 10 Qr QR 5p 0f fF"

    sequence[4]= "1A 0P 2p 2A 0H 0P gG 0A 2p 0a 1A"

    sequence[5]= "0P 10 Qr 1a 2a 2p 0a 4A"

    sequence[6]= "0N mM 0P Qr 20 Qs 1p 0A 0C dC"

    sequence[7]= "1K 0P jJ 0A 2p 0A 0E fF"

    sequence[8]= "1P Qr qt Qr 0p 10"

    sequence[9]= "0P 10 Qq 20 Qs 1p 0a 2A"

    

    sequence["A"]= "0A 0P 2a 2p 6F 0P ef 0f ee 2p 0A"

    sequence["B"]= "0P 10 Qr 1p 5P QR 5a 4p 0A 20"

    sequence["C"]= "0N mM 0P Qr 20 Qr 0p 5a"

    sequence["D"]= "0P 10 Qq 20 Qq 1A 4p 0A 20"

    sequence["E"]= "0A 2a 0P 1p 0F eE 0A 0P 2A 4A 2p"

    sequence["F"]= "0A 2a 0P 1F 0p eE 0A 0P 2A 4p 0A 20"

    sequence["G"]= "0F ef 0P 1a 10 qr 20 qr 0p 3A"

    sequence["H"]= "0A 2a 0P 2p 0C DC 0P 4p 0a 2a 0P 4p 0A"

    sequence["I"]= "0P 2p 0A 4A 0P 2p 5A 0P 4p 0A 10"

    sequence["J"]= "0A 4a 0P 2a 30 qr 0p 0a 0e eE"

    sequence["K"]= "0A 0P 4p 0a 2C 0P Da dp 0C"

    sequence["L"]= "0A 4P 8a 2p"

    sequence["M"]= "0A 0P 4a 0f ee 0e EE 4p 0A"

    sequence["N"]= "0A 0P 4E Fe 4p 8a"

    sequence["O"]= "1P Qq 20 Qr 20 Qq 0p 10"

    sequence["P"]= "0A 0P 4a 10 qr 1p 0A 0C dC"

    sequence["Q"]= "1P Qq 20 Qr 20 Qq 0p 0A 1a 0c 0P cp 0C"

    sequence["R"]= "0A 0P 4a 10 qr 1A 0C dp 0C"

    sequence["S"]= "0a 5P Qs qs 0p 3A"

    sequence["T"]= "0A 4a 0P 2p 5a 0P 4p 0A 10"

    sequence["U"]= "0a 8P 30 Qr 3p 7P 5p 0a"

    sequence["V"]= "0A 4J 0P Jj 0j jp 0J 8a"

    sequence["W"]= "0A 4P 8e eE 0E Ee 4p 8a"

    sequence["X"]= "0F 0P fp 0f 6f 0P fp 0F"

    sequence["Y"]= "1A 0P 2E ep Ee 0e 0P ep 0E 8a"

    sequence["Z"]= "0A 4a 0P 2F Ff 2p"

    sequence[" "]= "20"  'space

    sequence["-"]= "0A 2a 0P 2p 0a 2A"  'hyphen

    

    For n=1 to (1+Text.GetLength(sequence[char]))/3

      movechar=text.GetSubText(sequence[char],n*3-2,1)

      unicode=Text.GetCharacterCode(movechar)

      If unicode>64 And unicode<91 Then  'capital letter

        movesign=-1

        movechar=text.ConvertToLowerCase(movechar)

      Else

        movesign=1

      EndIf

      

      turnchar=text.GetSubText(sequence[char],n*3-1,1)

      turn_unicode=Text.GetCharacterCode(turnchar)

      If turn_unicode>64 And turn_unicode<91 Then  'capital letter

        turnsign=-1

        turnchar=text.ConvertToLowerCase(turnchar)

      Else

        turnsign=1

      EndIf

      

      If movechar="0" Then

        ' do nothing

      ElseIf movechar="1" Then

        Turtle.Move(100)

      ElseIf movechar="2" Then

        Turtle.Move(200)

      ElseIf movechar="3" Then

        Turtle.Move(300)

      ElseIf movechar="4" Then

        Turtle.Move(400)

      ElseIf movechar="5" Then

        Turtle.Move(-100)

      ElseIf movechar="6" Then

        Turtle.Move(-200)

      ElseIf movechar="7" Then

        Turtle.Move(-300)

      ElseIf movechar="8" Then

        Turtle.Move(-400)

      ElseIf movechar="9" Then

        Turtle.Move(25)

      ElseIf movechar="c" Then

        Turtle.Move(movesign*141.4)

        'Motor.Move(ports,10,141.4*s,1)

      ElseIf movechar="d" Then

        Turtle.Move(movesign*282.8)

        'Motor.Move(ports,10,282.8*s,1)  

      ElseIf movechar="e" Then

        Turtle.Move(movesign*223.6)

      ElseIf movechar="f" Then

        Turtle.Move(movesign*447.2)

      ElseIf movechar="g" Then 

        Turtle.Move(movesign*316.2)

      ElseIf movechar="j" Then 'sqr(5)

        Turtle.Move(movesign*412.3)

      ElseIf movechar="m" Then

        Turtle.Move(movesign*360.6)

      ElseIf movechar="q" Then  'draw arc

        If turnchar="q" Then

          imax=45  '90° in 45 steps of 2° each

        ElseIf turnchar="r" Then

          imax=90  '180°

        ElseIf turnchar="s" Then

          imax=135   '270°

        ElseIf turnchar="t" Then

          imax=180   '360°

        EndIf

        For i=1 to imax

          Turtle.Move(turnsign*3.49)  ' 2*pi*100/(4*45)  =3.49

          Turtle.Turn(movesign*2)

        EndFor

      EndIf

      

      If turnchar="0" Then

        ' do nothing

      ElseIf turnchar="a" Then

        Turtle.Turn(turnsign*90)

      ElseIf turnchar="b" Then

        Turtle.Turn(turnsign*180)

      ElseIf turnchar="c" Then

        Turtle.Turn(turnsign*45)

      ElseIf turnchar="e" Then

        Turtle.Turn(turnsign*26.565)

      ElseIf turnchar="f" Then

        Turtle.Turn(turnsign*63.434)

      ElseIf turnchar="g" Then

        Turtle.Turn(turnsign*18.435)

      ElseIf turnchar="h" Then

        Turtle.Turn(turnsign*71.565)

      ElseIf turnchar="j" Then

        Turtle.Turn(turnsign*14.036)

      ElseIf turnchar="k" Then

        Turtle.Turn(turnsign*75.963)

      ElseIf turnchar="m" Then

        Turtle.Turn(turnsign*33.69)

      ElseIf turnchar="n" Then

        Turtle.Turn(turnsign*56.31)

      ElseIf turnchar="p" Then

        If turnsign=1 Then

          Turtle.PenUp()

        Else

          Turtle.PenDown()

        EndIf

      EndIf

    EndFor

    busy="False"

  EndIf

EndSub

Note that Small Basic has a bug in which if your use the command     GraphicsWindow.Clear()  then it becomes impossible to show the turtle again. Since in this program I wanted to allow you, the user, to have turtle draw characters again and again, clearing the previous drawing before starting the new one, I had to use the 'workaround code' above (in bold) which deletes all the previous lines left by the turtle, each of which is actually a 'shape'.

You may notice when you run the program that some characters (such as 'B' are not quite drawn perfectly). This is because of the rounding errors that often occur when the distances and angles are given, and also because of the need to draw the arcs as a set of straight lines since Small Basic has no arc-drawing function. 

These drawing errors will become a very big issue when we move from the Small Basic graphics window to a real robot, which is the NEXT STEP.