TinyLogo

© 1999 Timothy Lipetz

Sample Procedure Files

Topics on this page: How to Load Samples, Loops, Trees, Music, Math, Draw, TicTac, Animate, Hangman

See also: TinyLogo Main, Beginners Guide, Advanced Information, Built-in Procedures, Samples

These sample programs should give you a few ideas about what you can do with TinyLogo. They certainly do not demonstrate everything, but I hope they give you some ideas of your own.

How to Load Samples

To load samples onto your Palm:

  1. Load the program TinyLogoSamples.prc in the usual way for your Palm handheld computer.
  2. Run the program TinyLogoSamples - it will write the six sample TL_ memos to the memopad.
  3. You can then remove the program, TinyLogoSamples. It is no longer needed.

Now for each TL_ memo:

  1. Start TinyLogo from scratch (this will avoid using up too much memory.)
  2. Use the TinyLogo load command, for example, load "loops.
  3. The descriptions below indicate which procedures to try, for example, loopdemo.

Loops

Loops was the doodling that got this whole TinyLogo project started. It uses a procedure decomposition of the program based on the geometric patterns in the drawing. Try loopdemo and then experiment with the loops procedure.

TL_loops
; Draws looping "doodles"
; params - :s=side :b=blocks
; by Timothy Lipetz

to hook :s
fd :s rt 90 fd :s rt 90 fd prd 3 :s rt 90
end

to edge :s
rep 2 [ hook :s ]
end

to incorner :s
hook :s
end

to join :s
rep 2 [ fd prd 3 :s rt 90 ]
end

to insquare :s :b
rep 4 [ rep dif :b 2 [ edge :s join :s ] incorner :s join :s ]
end

to outcorner :s
rep 3 [ hook :s ]
end

to outsquare :s :b
rep 4 [ rep dif :b 2 [ edge :s join :s ] outcorner :s join :s ]
end

to loops :s :b
ifelse eq :b 1
[ rep 4 [ hook :s ] ]
[ outsquare :s :b
if gt :b 2 [
pu lf 90 bk dif prd :s prd 4 :b prd :s 6 rt 90 bk prd :s 2
pd insquare :s sub1 :b
]
]
end

to loopdemo
tu cs sh 90 pu sxy -75 26 pd loops 10 4 pu sxy -15 6 pd loops 10 1
end

Trees

Trees are a classic Logo demonstration. They very simply show the power of recursion by reusing the same procedure for branches, sub-branches of them, etc. This demonstrates the Fractal nature of tree growth. There are two versions of tree here. The tree2 procedure adds a settable angle, a reducing length and a random element for a more realistic result. Try treedemo and then experiment with the tree2 procedure.

TL_trees
; Draws fractal trees
; params - :d=depth :l=length :a=angle
; By Timothy Lipetz

to tree1 :d :l
fd :l
if ne :d 0[rt 30 tree1 sub1 :d :l lf 60 tree1 sub1 :d :l rt 30]
bk :l
end

to tree2 :d :l :a
fd :l
if ne :d 0[
rt :a tree2 sub1 :d quo prd 9 :l sum 9 rnd 7 :a
lf :a lf :a tree2 sub1 :d quo prd 9 :l sum 9 rnd 7 :a rt :a
]
bk :l
end

to init
sxy 0 -70 sh 90 cs
end

to treedemo
tu init tree1 3 25
p [ "Now "tree2 ]
init tree2 5 36 20
end

Music

The play30 procedure demonstrates how to walk through a list using a recursive procedure. In this case all notes are played for equal duration (so I did have to simplify Beethoven's melody a little). How would you rewrite this to vary the duration of notes? Try the odejoy procedure.

TL_music
; Plays Ode to Joy (simplified)
; params - :i=list of notes
; By Timothy Lipetz

to play30 :i
if eq :i [] [ stop ]
note fi :i 30
play30 bf :i
end

to odeA
play30[16 16 17 19 19 17 16 14 12 12 14 16 16 14 14]
end

to odeB
play30[16 16 17 19 19 17 16 14 12 12 14 16 14 12 12]
end

to odeC
play30[14 14 16 12 14 17 16 12 14 17 16 14 12 14 7]
end

to odejoy
odeA odeB odeC odeB
end

Math

Mathematicians love recursion. It is the ultimate "reduce it to a problem we have already solved." However programmers need to decided when to use recursion. Notice the Fibonacci number examples. By changing the two regular recursive calls in the pure form, fib1, to a single tail-recursion, fib3, we can dramatically improve performance.

TL_math
;some math based recursive procs

; by Timothy Lipetz

;Triangle numbers
to tri :i
if eq :i 1[op 1]
op sum :i tri dif :i 1
end

;Factorical numbers
to fact :i
if eq :i 1[op 1]
op prd :i fact dif :i 1
end

;Finbonacci numbers

;This is a mathematically
;'pure' form of fibonacci- not
;able to do big numbers - very
;inefficient
; fib1 10 - took 53 seconds
to fib1 :i
if le :i 2[op 1]
op sum fib1 dif :i 1 fib1 dif :i 2
end

;Here is a more iterative form
;This works too, but 2nd op
;prevents tail recursion - still
;not able to do big numbers
; fib2 10 - took 5 seconds
to _f2 :i :a :b
if eq :i 1[op :b]
op _f2 sub1 :i :b sum :a :b
end
to fib2 :i
op _f2 :i 0 1
end

;Here is another iterative fib.
;The single op in _f3 works
;because of tail recursion.
;This can do big numbers
; fib3 10 - took 7 seconds
; fib3 45 - took 21 seconds -
;Beyond that, the numbers are
;bigger than the Palm handles.
to _f3 :i :a :b
if eq :i 1[op :b]
_f3 sub1 :i :b sum :a :b
end
to fib3 :i
op _f3 :i 0 1
end

Draw

These procedures provide two drawing programs. The first one, draw, is a simple Etch-a-sketch style program. The second, reflect,produces a 4-way kaleidoscope drawing. Notice how the main part of the work is done by two "internal" procedures, _d and _rfl. Each of these uses tail recursion to keep repeating as long as needed. Also, each of these is called by a wrapper "main" procedure which gives instructions and then starts things off.

TL_draw
; Drawing programs
; by Timothy Lipetz

to dinstr
p ["Tap "screen "to "draw. "Tap "bottom "to "stop.]
end

to _d
readpen
if lessthan peny -70 [ stop ]
setxy penx peny
_d
end

to draw
tu dinstr readpen _d
end

to line :x1 :y1 :x2 :y2
pu sxy :x1 :y1
pd sxy :x2 :y2
end

to _rfl :x :y
rp
if lt py -70 [ stop ]
line :x :y px py
line :x dif 0 :y px dif 0 py
line dif 0 :x dif 0 :y dif 0 px dif 0 py
line dif 0 :x :y dif 0 px py
_rfl px py
end

to reflect
tu dinstr rp _rfl px py
end

TicTac

This TicTacToe program is based on an old C version that was floating around UNIX circles in the early 1980's. I highly recommend that you try running it a few times before you read the code to see how it was done. To start it, run tictac.

Warning, this program is not for the humor-impaired. :-}

Animate

These two simple procedures demonstrate bitmap graphics using icons, text and boxes. They also demonstrate non-blocking input - notice that the spinning globe does not stop to wait for your input. This type of input is common on most video games and modern user interfaces. Finally, this includes an example of a make-variable. The two icons files which are loaded were created as memos by the TinyLogoSamples program. Try the animate procedure.


TL_animate

; place stars & moons while
; earth revolves -
; demonstrates icons &
; non-blocking pen detection &
; make-variables
; by Timothy Lipetz
;
; Var thg "inum=icon number

to earth
rep 18 [
icon cnt -40 40
if pen[
ifelse in -40 40 32 32
[mk "inum mod add1 thg "inum 8]
[icon sum 20 thg "inum px py]
]
]
earth
end


to animate
tu cs ht pn
pt "Loading_icons. -60 60
li "eartha
li "earthb
cs pt ["Tap "sky "to "draw "or "Earth "to "change "icon] -80 75
pr box -80 80 160 160
icon 20 30 0
icon 21 -30 -40
icon 22 50 20
mk "inum 0
earth
end

Hangman

I wanted an example of text manipulation so I wrote this Hangman game. It does run slow if the target word gets longer than about four letters. However, it does contains several good examples. Notice how the makewsf procedure uses tail recursion to walk through the target word while building up the word so far. The _hm procedure uses tail or regular recursion once for each guessed letter. Try the hangman procedure with your target word as an argument.


TL_hangman

; by Timothy Lipetz
;Var thg "wsf=word so far
;Var :tw=target word
;Var :pwsf=partial word so far
;Var :ptw=partial target word
;Var :g=letter guessed
;Var :gl=guesses left
;Var thg "gok=guess ok?
;Var thg "won=won?

to makewsf :pwsf :ptw :g :tw
if eq len :ptw 0 [stop]
if eq len :ptw len :tw [mk "wsf bf "x p :g]
ifelse eq fi :ptw :g
[mk "wsf wd thg "wsf :g mk "gok t]
[mk "wsf wd thg "wsf fi :pwsf]
if eq la thg "wsf "? [mk "won f]
makewsf bf :pwsf bf :ptw :g :tw
end

to initwsf :ptw
if eq len :ptw 0[stop]
mk "wsf wd thg "wsf "?
initwsf bf :ptw
end

to _hm :tw :gl
mk "gok f
mk "won t
makewsf thg "wsf :tw
fi readline se se :gl ["left "__ "Word "so "far...] thg "wsf :tw
if thg "won [p "You p "won... pl :tw halt]
if eq :gl 1 [p "You p "lost. p "Solution... pl :tw halt]
if not thg "gok [_hm :tw sub1 :gl]
_hm :tw :gl
end

to hangman :tw
mk "wsf bf "x ;empty word
initwsf :tw
p "Used...
_hm :tw 6
end

See also: TinyLogo Main, Beginners Guide, Advanced Information, Built-in Procedures, Samples