LOGO-L> parallel turtles in mswlogo
Author Message
LOGO-L> parallel turtles in mswlogo

Very nice, I especially like the use of the iseq function.

Quote:

> hi,
> i cooked up something, and some of you might be interested.
> parallel turtles in mswlogo.

> mswlogo has multiple turtles
> but using them is somewhat tedious.
> you have to do something like

> setturtle :x
> do.whatever.the.turtle.is.suppsed.to
> setturtle :x + 1
> do.whatever.the.turtle.is.suppsed.to

> i wanted to tell the turtles what they should do,
> and i wanted to be able to ask all the turtles
> the same question

> so we have the following new procedures and functions
> to tell.turtle :who :action
> to tell.turtles :who :action

> tell.turtle and ask.turtle are for one turtle only
> so the 1st agrument (:who) has to be a number
> the second argument has to be a legal instruction
> (or sequence of instructions)

> tell.turtle 0 [fd 10]
> will move turtle 0 forward 10 steps
> will give you the position of turtle 0

> to deal with multiple turtles concurrently
> have lists as 1st argument

> tell.turtle [0 1 2 3] [fd 10]
> will mov 4 turtles forward
> (use iseq 0 100 for talking to 100 turtles at the same time)

> ask.turtle iseq 0 99 [pos]
> will give a list containing the positions of te first 100
> turtles.

> now:
> DRUM RRRRRRRRRRRRRRRROOOOOOOOOOOOOOLLLLLLLLLLLLLLLLLLLLLLLL

> parallel execution

> do.par :who :action
> takes a list of turtle numbers and a sequence of actions
> and performs these action "interwovev"

> do.par iseq 0 9 [[fd 10] [rt 10] [fd 10]]

> will do fd 10 for all turtles,
> then rt 90 for all turtles, and then fd 10 for all turtles
> again.
> each one of the bracketed subactions will be performed for all
> turtles, only then the next subaction will be performed.
> if :actions contains only one word which is the name
> of a user defined procedure
> this procedure will be "unwoven", i.e. each of its steps
> will be performed for all the turtle before the
> next step is performed for all turtles.

> nowit should be clear what
> repeat.par :n.of.times :who :actions
> does
> it is a parallel repeat,
> it is repeated execution of do.par

> in all the actions,
> turtle will give you the number of the turtle just
> performing the action

> in repeat.par repcount will give the number of the current repetition

> here are some examples

> to demo1
> tell.turtles iseq 0 10 [setpos list 20 * turtle 0]
> tell.turtles iseq 0 10 [fd 5 * turtle]
> wait 20
> tell.turtles iseq 0 10 [fd 5 * turtle]
> wait 20
> tell.turtles iseq 0 10 [fd 5 * turtle]
> wait 20
> end

> to demo2
> cs
> do.par iseq 0 10 [[fd 10 + 10 * turtle] [rt 90] [fd 10 + 10 * turtle]
> [rt 90] ~
>         [fd 10 + 10 * turtle] [rt 90] [fd 10 + 10 * turtle] [rt 90]]
> end

> to demo3
> cs
> repeat.par 360 iseq 0 10 [fd 0.2 * (turtle + 1) rt 1]
> end

> to demo4
> cs
> repeat.par 20 iseq 0 10 [[fd repcount * (1 + turtle)] [rt 90]]
> end

> -=-=-=-=-=-=-=

> here is the "turtles in love" problem.
> in this problem, each turtle is in love with the next turtle
> (in the sense 0->1->2->3->0)
> and always moves towards the love one

> to turtles.in.love
> setup
> repeat.par 300 iseq 0 3 [approach]
> end

> to setup
> tell.turtles iseq 0 3 [penup]
> tell.turtle 0 [setpos [-150 -150]]
> tell.turtle 1 [setpos [-150 150]]
> tell.turtle 2 [setpos [150 150]]
> tell.turtle 3 [setpos [150 -150]]
> tell.turtles iseq 0 3 [pendown]
> end

> to the.loved.one :n
> if :n = 3 [output 0]
> output :n + 1
> end

> to approach
> fd 1
> end

> and now, the library procuedure

> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=

> localmake "oldturtle turtle
> setturtle :who
> localmake "result invoke :question :who
> setturtle :oldturtle
> output :result
> end

> output map [ask.turtle ? :question] :who
> end

> to do.par :who :actions
> if emptyp :actions [stop]
> ifelse and (wordp :actions) (not (numberp :actions)) ~
>         [do.par.helper :who butfirst text :actions] ~
>         [do.par.helper :who :actions]
> end

> to do.par.helper :who :actions
> if emptyp :actions [stop]
> if not listp first :actions [tell.turtles :who :actions stop]
> do.par.helper.recur :who :actions
> end

> to do.par.helper.recur :who :actions
> if emptyp :actions [stop]
> tell.turtles :who first :actions
> do.par.helper.recur :who butfirst :actions
> end

> to repeat.par :n.of.times :who :actions
> repeat :n.of.times [do.par :who :actions]
> end

> to tell.turtle :who :action
> localmake "oldturtle turtle
> setturtle :who
> run :action
> setturtle :oldturtle
> end

> to tell.turtles :who :action
> foreach :who [tell.turtle ? :action]
> end

>         do.par do.par.helper do.par.helper.recur repeat.par]
> ---------------------------------------------------------------

--
===============================================================

http://www.*-*-*.com/
The www page contains some very powerful educational software.
Our single most important investment is our kids.
---------------------------------------------------------------

Wed, 25 Sep 2002 03:00:00 GMT
LOGO-L> parallel turtles in mswlogo
Four turtles being in love with each other was just too much for this sorta
old-fashioned fellow.   Dale

to approach
fd 1
end

to setup
tell.turtles iseq 0 3 [penup]
tell.turtle 0 [setpos [-150 -150]]
tell.turtle 1 [setpos [-150 150]]
tell.turtle 2 [setpos [0 150]]
tell.turtle 3 [setpos [150 -150]]
tell.turtles iseq 0 3 [pendown]
end

to test.for.wall
if pixel = [0 0 0] [bk 10 rt 90]
end

to the.loved.one :n
test.for.wall
if :n = 3 [output 0]
output :n + 1
end

to turtles.in.love
cs
setpensize [3 3]
repeat 45[fd 2 rt 1]
setpensize[1 1]
setup
repeat.par 300 iseq 0 3 [approach]
end
---

---------------------------------------------------------------

Wed, 25 Sep 2002 03:00:00 GMT
LOGO-L> parallel turtles in mswlogo
here is a slightly imporved version of my parallel turtles
(thanks brian)
and a turtle race game
(which is a graphical illustration of the sum of random variables,
but if you are not interested in such things, just forget it
and enjoy the race)

-=-=-=-=-=   file: multiturtle.lgo

localmake "oldturtle turtle
setturtle :who
localmake "result (invoke :question)
setturtle :oldturtle
output :result
end

output map [ask.turtle ? :question] :who
end

to do.par :who :actions
if emptyp :actions [stop]
ifelse and (wordp :actions) (not (numberp :actions)) ~
[do.par.helper :who butfirst text :actions] ~
[do.par.helper :who :actions]
end

to do.par.helper :who :actions
if emptyp :actions [stop]
if not listp first :actions [tell.turtles :who :actions stop]
do.par.helper.recur :who :actions
end

to do.par.helper.recur :who :actions
if emptyp :actions [stop]
tell.turtles :who first :actions
do.par.helper.recur :who butfirst :actions
end

to repeat.par :n.of.times :who :actions
repeat :n.of.times [do.par :who :actions]
end

to tell.turtle :who :action
localmake "oldturtle turtle
setturtle :who
run :action
setturtle :oldturtle
end

to tell.turtles :who :action
foreach :who [tell.turtle ? :action]
end

do.par do.par.helper do.par.helper.recur repeat.par]

-=-=-=-=-=-=-=-=-=-=  file: race.lgo

to max :a :b
if :a > :b [output :a]
output :b
end

to max.list :l
output reduce "max :l
end

to race
while [(max.list ask.turtles iseq 0 9 [xcor]) < 300 ] ~
[tell.turtles iseq 0 9 [forward 1 + random 6]]
print list "The winner is: ~
count member 300 map [ifelse ? > 300 [300] ?]  ~
end

to setup
tell.turtle 0 [ht]
tell.turtle 0 [penup]
tell.turtle 0 [setxy 300 -150]
tell.turtle 0 [pendown]
tell.turtle 0 [fd 300]
tell.turtle 0 [penup]
tell.turtle 0 [home]
tell.turtle 0 [st]
tell.turtles iseq 0 9 [penup]
tell.turtles iseq 0 9 [setxy -300 20 * turtle - 90]
tell.turtles iseq 0 9 [setheading 90]
tell.turtles iseq 0 9 [pendown]
end