Jump to content
IGNORED

Any interest in Atari LOGO examples?


Recommended Posts

On 11/9/2022 at 6:45 AM, DocSavage2001 said:

Yeah, these are some of the issues I ran into when I was trying to implement in Atari LOGO. I did say it was a challenge! :) The other higher order functions I was able to get around the lack of Atari equivalents but not this one.

 

Dave

So what are the other problems you ran into with CASCADE? I still don't think I can get a generic one that takes a variable number of parameters, but things like CASCADE.2, CASCADE.2R, CASCADE.3, etc. are possible, if a bit messy,

 

to piglatin :word
output (cascade.r [vowelp first ?] ~
                  [word bf ? first ?] ~
                  :word ~
                  [word ? "ay])
end


to fibonacci :n
output (cascade.2 :n [?1 + ?2] 1 [?1] 0)
end


to fibonacci :n
output (cascade.2r :n [?1 + ?2] 1 [?1] 0 [?1])
end

 

Link to comment
Share on other sites

12 minutes ago, yetanothertroll said:

So what are the other problems you ran into with CASCADE? I still don't think I can get a generic one that takes a variable number of parameters, but things like CASCADE.2, CASCADE.2R, CASCADE.3, etc. are possible, if a bit messy,

 

to piglatin :word
output (cascade.r [vowelp first ?] ~
                  [word bf ? first ?] ~
                  :word ~
                  [word ? "ay])
end


to fibonacci :n
output (cascade.2 :n [?1 + ?2] 1 [?1] 0)
end


to fibonacci :n
output (cascade.2r :n [?1 + ?2] 1 [?1] 0 [?1])
end

 

I'll get back to you on the exact examples of cascade I was trying to use. I have it here somewhere.

 

Dave

  • Thanks 1
Link to comment
Share on other sites

On 11/15/2022 at 2:21 PM, DocSavage2001 said:

I'll get back to you on the exact examples of cascade I was trying to use. I have it here somewhere.

 

Dave

Muchas gracias. In the meantime, I have a style question. Should monster functions always be broken up? For example,

 

TO COUNTOFF :X :FINISH
( TYPE :X CHAR 32 )
PRINT ENGL :X
IF NOT ( :X < :FINISH ) [STOP]
IF NOT ( :X < ( :X + 1 ) ) [STOP]
COUNTOFF ( :X + 1 ) :FINISH
END

TO ENGL :X
IF NOT ( :X = ROUND :X ) [OP ENGL ROUND :X]
IF :X < 0 [OP ( SE "NEGATIVE ENGL - :X )]
IF NOT ( 1.0E+15 > :X ) [OP ( SE ( ENGL INT ( :X / 1.0E+15 ) ) "QUADRILLION ( ENGL REMAINDER :X 1.0E+15 ) )]
IF NOT ( 1E+12 > :X ) [OP ( SE ( ENGL INT ( :X / 1E+12 ) ) "TRILLION ( ENGL REMAINDER :X 1E+12 ) )]
IF NOT ( 1000000000 > :X ) [OP ( SE ( ENGL INT ( :X / 1000000000 ) ) "BILLION ( ENGL REMAINDER :X 1000000000 ) )]
IF NOT ( 1000000 > :X ) [OP ( SE ( ENGL INT ( :X / 1000000 ) ) "MILLION ( ENGL REMAINDER :X 1000000 ) )]
IF NOT ( 1000 > :X ) [OP ( SE ( ENGL INT ( :X / 1000 ) ) "THOUSAND ( ENGL REMAINDER :X 1000 ) )]
IF NOT ( 100 > :X ) [OP ( SE ( ENGL INT ( :X / 100 ) ) "HUNDRED ( ENGL REMAINDER :X 100 ) )]
IF NOT ( 90 > :X ) [OP ( SE "NINETY ENGL :X - 90 )]
IF NOT ( 80 > :X ) [OP ( SE "EIGHTY ENGL :X - 80 )]
IF NOT ( 70 > :X ) [OP ( SE "SEVENTY ENGL :X - 70 )]
IF NOT ( 60 > :X ) [OP ( SE "SIXTY ENGL :X - 60 )]
IF NOT ( 50 > :X ) [OP ( SE "FIFTY ENGL :X - 50 )]
IF NOT ( 40 > :X ) [OP ( SE "FORTY ENGL :X - 40 )]
IF NOT ( 30 > :X ) [OP ( SE "THIRTY ENGL :X - 30 )]
IF NOT ( 20 > :X ) [OP ( SE "TWENTY ENGL :X - 20 )]
IF 19 = :X [OUTPUT "NINETEEN]
IF 18 = :X [OUTPUT "EIGHTEEEN]
IF 17 = :X [OUTPUT "SEVENTEEN]
IF 16 = :X [OUTPUT "SIXTEEN]
IF 15 = :X [OUTPUT "FIFTEEN]
IF 14 = :X [OUTPUT "FOURTEEN]
IF 13 = :X [OUTPUT "THIRTEEN]
IF 12 = :X [OUTPUT "TWELVE]
IF 11 = :X [OUTPUT "ELEVEN]
IF 10 = :X [OUTPUT "TEN]
IF 9 = :X [OUTPUT "NINE]
IF 8 = :X [OUTPUT "EIGHT]
IF 7 = :X [OUTPUT "SEVEN]
IF 6 = :X [OUTPUT "SIX]
IF 5 = :X [OUTPUT "FIVE]
IF 4 = :X [OUTPUT "FOUR]
IF 3 = :X [OUTPUT "THREE]
IF 2 = :X [OUTPUT "TWO]
IF 1 = :X [OUTPUT "ONE]
IF 0 = :X [OUTPUT []]
END

 

Link to comment
Share on other sites

On 11/10/2022 at 7:50 AM, Gibstov said:

I think it may also pull the number of parameters that the Template(Procedure) takes not sure...I am just guessing here...but that seems logical

 

I'll have to look into whether Atari LOGO has a way to check how many parameters a function expects or whether it returns a value, other than maybe shenanigans like saving the workspace to a temp file on diskette and then reading it as text. My attempt at APPLY just shoves everything into a flattened list, passes it to RUN and hopes for the best

Link to comment
Share on other sites

Hey, has anyone used WHEN to have the turtle autonomously react to encountering drawn figures or other turtles? It might be just the thing for a Langton's Ant program,

 

https://en.wikipedia.org/wiki/Langton's_ant

 

LangtonsAntAnimated.gif

 

http://www.langtonant.com/

 

https://forums.craigslist.org/?ID=324659503

 

LangtonsAnt-nColor_LRRRRRLLR_70273.png

 

 

Spoiler

How do I delete this spoiler section thing 😂

 

  • Like 2
Link to comment
Share on other sites

  • 4 weeks later...
On 9/24/2020 at 10:06 AM, DocSavage2001 said:

Note that Atari Logo is not built for speed, so if you try something like solving for 10 rings, go grab some lunch!

The great news is that the CPU never gets below 1.074 mhz! And a normal Basic mode 0 has it running at 1.14 mhz. C&A is DMA heavy and therefore the CPU there runs at about 1.1 mhz, unfortunately.

Link to comment
Share on other sites

  • 3 months later...

I'm having to rework much of the list processing code I've been playing with. It appears that recursive functions can be written in ways that don't blow up even when throwing around lists 1000+ elements long. Who knew? Some examples,

 

TO REV :LIST

OUTPUT REVERSE :LIST

END

 

TO REVERSE :LIST

OUTPUT REVERSE.1 :LIST [ ]

END

 

TO REVERSE.1 :LIST :RESULT

IF EMPTYP :LIST [OUTPUT :RESULT]

OUTPUT REVERSE.1 ( BUTFIRST :LIST ) ( FPUT FIRST :LIST :RESULT )

END

 

TO FFOR :N

OUTPUT FFOR.1 :N [ ]

END

 

TO FFOR.1 :N :RESULT
IF :N < 1 [OUTPUT :RESULT]
OUTPUT FFOR.1 ( :N - 1 ) FPUT :N :RESULT
END

 

TO FOR :FIRST :LAST :STEP
OP REV FOR.1 :FIRST :LAST :STEP [ ]
END

 

TO FOR.1 :N :LAST :STEP :ACCUMULATOR
IF ( :N + :STEP ) = :N [OUTPUT :ACCUMULATOR]
IF ( AND ( :STEP > 0 ) ( :N > :LAST ) ) [OUTPUT :ACCUMULATOR]
IF ( AND ( :STEP < 0 ) ( :N < :LAST ) ) [OUTPUT :ACCUMULATOR]
OUTPUT FOR.1 ( :N + :STEP ) :LAST :STEP FPUT :N :ACCUMULATOR

END

 

EDIT: Some lines got mangled when pasting, and I added a space between the brackets with empty lists so they don't look like broken emojis or something [] Hopefully I fixed them all

 

The CompSci key phrase to Google is "tail recursion optimization"

Edited by yetanothertroll
Fixed up mangled pasted code
Link to comment
Share on other sites

The Apple Logo II Reference Manual has some interesting sample code, including math functions like logs and exponents as well as graphics routines for drawing things like circles.

 

Some of the code relies on local variables which shouldn't be hard to convert. Maybe the circle and curve code should adjust the number of steps based on the radius. There's no sense in drawing 36 segments for a circle 10 pixels wide! Or maybe there is if you managed to get your mitts on an Atari 1020 4-color pen plotter?

 

Anyway, the code samples start at page 255 of the manual, or 278 in the scanned PDF:

 

https://archive.org/details/Apple_Logo_II_Reference_Manual/page/n278

 

Edit: If you do have a 1020 plotter, here's how to get started using it with Logo:

 

https://www.atarimagazines.com/compute/issue46/060_1_FRIENDS_OF_THE_TURTLE.php

 

Edited by yetanothertroll
I can haz 1020?
  • Like 3
Link to comment
Share on other sites

  • 2 weeks later...

A few random thoughts. Langton's Ant might be ending up off the trail because of the .SETSCR aspect ratio. I might have to do a .SETSCR 1 so moving the turtle vertically by 1 will reliably draw one pixel each and every time.

 

Using WHEN 7 [ BLAH ] to measure execution time is useless. Heavy memory thrashing and automatic RECYCLE will cause the 'demon' to skip like a scratched record. Also, if the 'demon' manipulates a variable named, for example, "N while another procedure with a parameter :N is running, strange things happen. It's much better to use the system "jiffies" counters. Example code below.

 

The version of LOGO on the bootable "Atari_Logo_LCSI.atr" is either buggy or extremely sensitive to a corrupted diskette. Maybe it even caused the corrupted diskette. If it's a cartridge memory dump, maybe its being shoved into an AUTORUN.SYS and loaded into an environment it didn't expect deranged its I/O. I've been using "ATARI LOGO (C) 1983 LCSI.car" even with diskettes in the Altirra 4.10 emulator with much better results. In addition, the version of Atari DOS II 2.5 on the Atari_Logo_LCSI.atr can only see "D1: and "D2: while the version of Atari DOS II 2.5 on the Action! 3.6/3.7 boot .atr can also let LOGO see "D3:

 

Here are my adaptations of the Apple Logo II graphics sample code as well as my take on drawing circles and polygons. Also check out STOPWATCH and JIFFIES for ways to use the system jiffies counters. STOPWATCH doesn't try to account for rollovers every ~48 days. I didn't convert the jiffies to seconds because while there are 60 jiffies per second on NTSC, it could be only 50 on PAL systems.

 

Notice how the procedures and variables are all nicely alphabetized? The program to do that is below the graphics code. It does run out of memory on projects bigger than itself, but if you do use it to alphabetize a project and save it to a file, perhaps using SW "D2:SORTED.LG [SR "D1:MYSTUFF.LG [SP]] you should be able to load that "D2:SORTED.LG file into Logo and expect it to still work. Writing to cassettes with SW "C: tends to do odd things unfortunately, but reading from the cassette with SR "C: appears to work as one would expect. It's definitely a work in progress.

 

TO ; :Comment
END

TO ARCL :RADIUS :DEGREES
; [Adapted from Apple Logo II]
; [Reference Manual pg. 256]
ARCL.1 :RADIUS :DEGREES 2 * :RADIUS * PI / 36 REMAINDER :DEGREES 10
END

TO ARCL.1 :RADIUS :DEGREES :STEP :REM
REPEAT INT ( :DEGREES / 10 ) [LT 5 FD :STEP LT 5]
IF :REM > 0 [FD :STEP * :REM / 10 LT :REM]
END

TO ARCR :RADIUS :DEGREES
; [Adapted from Apple Logo II]
; [Reference Manual pg. 256]
ARCR.1 :RADIUS :DEGREES 2 * :RADIUS * PI / 36 REMAINDER :DEGREES 10
END

TO ARCR.1 :RADIUS :DEGREES :STEP :REM
REPEAT INT ( :DEGREES / 10 ) [RT 5 FD :STEP RT 5]
IF :REM > 0 [FD :STEP * :REM / 10 RT :REM]
END

TO CCIRCLE :RADIUS
; [Draw 'good enough' poly - circle]
; [centered at Turtle position]
POLYGON :RADIUS 6 + 2 * INT :RADIUS / 6
END

TO CIRCLE :RADIUS
; [From Apple Logo II Reference]
; [Manual pg. 244]
REPEAT 60 [FD :RADIUS * 3.14159 / 30 RT 6]
END

TO CIRCLEL :RADIUS
; [Adapted from Apple Logo II]
; [Reference Manual pg. 256]
CIRCLEL.1 :RADIUS 2 * :RADIUS * PI / 36
END

TO CIRCLEL.1 :RADIUS :STEP
REPEAT 36 [LT 5 FD :STEP LT 5]
END

TO CIRCLER :RADIUS
; [Adapted from Apple Logo II]
; [Reference Manual pg. 256]
CIRCLER.1 :RADIUS 2 * :RADIUS * PI / 36
END

TO CIRCLER.1 :RADIUS :STEP
REPEAT 36 [RT 5 FD :STEP RT 5]
END

TO JIFFIES
; [Get Jiffies counters guarding]
; [against wraparound issues]
OP JIFFIES.1 1 1 1 0 0 0
OP JIFFIES.1 0 0 0 0 0 -1
END

TO JIFFIES.1 :P18 :P19 :P20 :C18 :C19 :C20
; [( PR "JIFFIES.1 :P18 :P19 :P20 :C18 :C19 :C20 )]
IF AND ( :C18 = :P18 ) AND ( :C19 = :P19 ) NOT ( :C20 < :P20 ) [OP ( SE :C18 :C19 :C20 )]
OP JIFFIES.1 :C18 :C19 :C20 .EXAMINE 18 .EXAMINE 19 .EXAMINE 20
END

TO PI
OUTPUT 3.14159265
END

TO POLYDEMO :N
POLYDEMO.1 3 :N ( SE "SETPN PN PEN )
END

TO POLYDEMO.1 :S :N :PENSTATE
IF :N < :S [RUN :PENSTATE STOP]
PD SETPN REMAINDER :S + 2 3
( TYPE :S CHAR 32 "SIDES CHAR 32 )
( TYPE NODES CHAR 32 "NODES CHAR 32 )
( PR STOPWATCH [POLYGON 55 :S] "JIFFIES )
POLYDEMO.1 :S + 1 :N :PENSTATE
END

TO POLYGON :APOTHEM :SIDES
; [Draw polygon centered at Turtle]
; [Odd sided shapes like triangles]
; [will point in the Turtle Heading]
; [Triangles in particular will be]
; [3 times as high as the Apothem!]
; [Try POLYGON 50 3 POLYGON 50 6]
POLYGON.1 :APOTHEM :SIDES FPUT PEN [ ]
END

TO POLYGON.1 :A :S :PENSTATE
POLYGON.2 :A :S :PENSTATE 0.5 * 360 / :S
END

TO POLYGON.2 :A :S :PS :THETA
; [Remember SOH CAH TOA ?]
POLYGON.3 :A :S :PS :THETA :A * TAN :THETA
END

TO POLYGON.3 :A :S :PS :THETA :O
PENUP BACK :A LEFT 90 BACK :O
RUN :PS
; [POLYGON.4 is what really]
; [needs to be lean and mean]
POLYGON.4 :S 2 * :O 2 * :THETA
PENUP FD :O RIGHT 90 FORWARD :A
RUN :PS
END

TO POLYGON.4 :N :D :PHI
REPEAT :N [FD :D RT :PHI]
END

TO STOPWATCH :BLOCK
; [Get time to run :BLOCK in Jiffies]
OUTPUT STOPWATCH.1 JIFFIES :BLOCK
END

TO STOPWATCH.1 :START :BLOCK
RUN :BLOCK
OP ( STOPWATCH.2 JIFFIES 0 ) - STOPWATCH.2 :START 0
END

TO STOPWATCH.2 :JIFFS :RESULT
IF EMPTYP :JIFFS [OUTPUT :RESULT]
OUTPUT STOPWATCH.2 BF :JIFFS :RESULT * 256 + FIRST :JIFFS
END

TO TAN :ANGLE
OUTPUT ( SIN :ANGLE ) / COS :ANGLE
END

 

TO ; :Comment
END

TO CAT
CAT.1 RC
END

TO CAT.1 :CHAR
IF EMPTYP :CHAR [STOP]
TYPE :CHAR
CAT.1 RC
END

TO DEFLESSP :DEF1 :DEF2
OP ( STRCMP ( FIRST BF FIRST :DEF1 ) ( FIRST BF FIRST :DEF2 ) ) < 0
END

TO LESSP :X :Y
OUTPUT :X < :Y
END

TO QSORT :LESSP :LIST
IF EMPTYP :LIST [OUTPUT [ ]]
OUTPUT QSORT.1 FIRST :LIST :LESSP BUTFIRST :LIST [ ] [ ]
END

TO QSORT.1 :PIVOT :LESSP :LIST :LESSTHAN :GREATERT
IF EMPTYP :LIST [OUTPUT SE ( QSORT :LESSP :LESSTHAN ) FPUT :PIVOT ( QSORT :LESSP :GREATERT )]
OP QSORT.2 :PIVOT :LESSP ( BUTFIRST :LIST ) :LESSTHAN :GREATERT ( FIRST :LIST ) RUN QSORT.3 :LESSP FIRST :LIST :PIVOT
END

TO QSORT.2 :PIVOT :LESSP :LIST :LESSTHAN :GREATERT :ITEM :ISLESS
OUTPUT QSORT.1 :PIVOT :LESSP :LIST ( IF :ISLESS [FPUT :ITEM :LESSTHAN] [:LESSTHAN] ) ( IF :ISLESS [:GREATERT] [FPUT :ITEM :GREATERT] )
END

TO QSORT.3 :LESSP :ITEM :PIVOT
OUTPUT ( SE "( :LESSP QSORT.4 :ITEM QSORT.4 :PIVOT ") )
END

TO QSORT.4 :OBJ
IF LISTP :OBJ [OUTPUT FPUT "( FPUT :OBJ FPUT ") [ ]]
IF NUMBERP :OBJ [OUTPUT ( SE "( :OBJ ") )]
IF EMPTYP :OBJ [OUTPUT ( SE "( "BF ""X ") )]
OUTPUT ( SE "( WORD "" :OBJ ") )
END

TO SANE
SETWRITE [ ]
SETREAD [ ]
END

TO SP
SP.1 RL [ ]
END

TO SP.1 :LINE :ACC
IF NOT LISTP :LINE [SP.2 :ACC STOP]
SP.1 RL FPUT :LINE :ACC
END

TO SP.2 :ACC
SP.4 SP.3 :ACC [ ] [ ] [ ]
END

TO SP.3 :ACC :NEWDEF :DEFS :VARS
IF AND EMPTYP :ACC EMPTYP :NEWDEF [OUTPUT FPUT :DEFS :VARS]
IF AND EMPTYP :ACC NOT EMPTYP :NEWDEF [OP FPUT ( FPUT :NEWDEF :DEFS ) :VARS]
IF AND EMPTYP FIRST :ACC EMPTYP :NEWDEF [OP SP.3 ( BUTFIRST :ACC ) [ ] :DEFS :VARS]
IF AND EMPTYP FIRST :ACC NOT EMPTYP :NEWDEF [OP SP.3 ( BF :ACC ) [ ] ( FPUT :NEWDEF :DEFS ) :VARS]
IF AND ( "MAKE = FIRST FIRST :ACC ) ( EMPTYP :NEWDEF ) [OP SP.3 ( BF :ACC ) [ ] :DEFS ( FPUT ( FIRST :ACC ) :VARS )]
OP SP.3 ( BUTFIRST :ACC ) ( FPUT FIRST :ACC :NEWDEF ) :DEFS :VARS
END

TO SP.4 :PROJECT
; [PRINT [* * *]]
; [SHOW FIRST :PROJECT]
; [PRINT [* * *]]
; [SHOW BUTFIRST :PROJECT]
; [PRINT [* * *]]
SP.5 QSORT "DEFLESSP FIRST :PROJECT TRUE
SP.5 QSORT "VARLESSP BUTFIRST :PROJECT FALSE
END

TO SP.5 :OBJ :PRBLANKS
IF AND EMPTYP :OBJ :PRBLANKS [PR [ ] STOP]
IF AND EMPTYP :OBJ NOT :PRBLANKS [STOP]
IF WORDP FIRST :OBJ [PRINT :OBJ STOP]
SP.5 FIRST :OBJ :PRBLANKS
SP.5 BUTFIRST :OBJ :PRBLANKS
END

TO SR :FILE :BLOCK
SETREAD :FILE
RUN :BLOCK
SETREAD [ ]
END

TO STRCMP :S1 :S2
IF AND EMPTYP :S1 EMPTYP :S2 [OP 0]
IF EMPTYP :S1 [OUTPUT -1]
IF EMPTYP :S2 [OUTPUT 1]
IF NOT ( ASCII :S1 ) = ( ASCII :S2 ) [OP ( ASCII :S1 ) - ( ASCII :S2 )]
OP STRCMP BUTFIRST :S1 BUTFIRST :S2
END

TO SW :FILE :BLOCK
SETWRITE [ ]
( TYPE [* * * SETWRITE] CHAR 32 ) SHOW :FILE
( TYPE [* * * RUN] CHAR 32 ) SHOW :BLOCK
REPEAT 10 [TYPE [*] WAIT 60] PR [LETS GOOOO!]
SETWRITE :FILE
RUN :BLOCK
SETWRITE [ ]
( PRINT [* * * SETWRITE [ ]]
END

TO VARLESSP :VAR1 :VAR2
OP ( STRCMP ( FIRST BF :VAR1 ) ( FIRST BF :VAR2 ) ) < 0
END


MAKE "BAR [2 3 4 5]
MAKE "BAZ "X
MAKE "FOO 1
MAKE "ZOO [ ]

 

Link to comment
Share on other sites

Yeah, I realize the project sorter's a bit of a mess. I'm gradually tightening it up, hopefully enough so that I can add some comments and still have it at least be able to sort itself without running out of nodes.

 

Most of the so-called "useful tools" in both the Atari and Apple Logo reference manuals are such a mess it's easier to go back to first principles like I did with CCIRCLE and POLYGON even if Apple's ARCL and ARCL aren't too bad, though it is kind of crazy that the "advanced" Quicksort is easier to implement in Logo than a 'simple' Insertion sort, so much so LCSI had to resort to global variables, a big no-no in functional languages like Lisp, Logo, Haskell, etc.

 

Logo is a good language for sharpening one's thinking. No wonder schools dropped it like a hot potato 😄

  • Like 2
Link to comment
Share on other sites

21 hours ago, yetanothertroll said:

Yeah, I realize the project sorter's a bit of a mess. I'm gradually tightening it up, hopefully enough so that I can add some comments and still have it at least be able to sort itself without running out of nodes.

 

Most of the so-called "useful tools" in both the Atari and Apple Logo reference manuals are such a mess it's easier to go back to first principles like I did with CCIRCLE and POLYGON even if Apple's ARCL and ARCL aren't too bad, though it is kind of crazy that the "advanced" Quicksort is easier to implement in Logo than a 'simple' Insertion sort, so much so LCSI had to resort to global variables, a big no-no in functional languages like Lisp, Logo, Haskell, etc.

 

Logo is a good language for sharpening one's thinking. No wonder schools dropped it like a hot potato 😄

I agree...I like to use LOGO (mostly FMSLogo) to quickly prototype ideas.  There are probably better languages..but I like how you can immediately test ideas in Logo without having to build or compile a whole program.

  • Like 2
Link to comment
Share on other sites

10 hours ago, Gibstov said:

I agree...I like to use LOGO (mostly FMSLogo) to quickly prototype ideas.  There are probably better languages..but I like how you can immediately test ideas in Logo without having to build or compile a whole program.

True, but doesn't FMS do too much? Even Atari's syntactic sugar is becoming more and more apparent. Does Logo really need a REPEAT primitive when it's pretty easy to roll your own even without blowing up the call stack? I bet FMS even does arctangent for you just like Apple Logo II!

atn 2.png

Tail.png

Link to comment
Share on other sites

  • 2 months later...

Bump. Also, logs, exponents, and the limits of nine digits of precision

16901709708263.thumb.png.601dacf6ede9c2511ce6a6f16a89f915.png

TO ; :Comment
END

TO EXP :NUM
; [e ^ :NUM or e * * :NUM general case]
( PRINT "EXP :NUM
IF :NUM < -4.5 [OP 1 / EXP - :NUM]
IF :NUM < 4.5 [OP 1 + EXPM1 :NUM]
OUTPUT SQ EXP ( :NUM / 2 )
END

TO EXPM1 :NUM
; [( EXP :NUM ) - 1 for :NUM close to 0]
( PRINT "EXPM1 :NUM
; [OUTPUT EXPM1.1 :NUM :NUM 1 1 0]
OUTPUT :NUM + EXPM1.1 :NUM SQ :NUM 2 2 0
END

TO EXPM1.1 :X :NUMER :DENOM :TERM :RESULT
OUTPUT EXPM1.2 :X :NUMER :DENOM :TERM :RESULT :RESULT + ( :NUMER / :DENOM )
END

TO EXPM1.2 :X :NUMER :DENOM :TERM :RESULT :NR
( PRINT "EXPM1.2 :X :NUMER :DENOM :TERM :RESULT :NR
IF :RESULT = :NR [OUTPUT :RESULT]
OP EXPM1.1 :X ( :NUMER * :X ) ( :DENOM * ( :TERM + 1 ) ) ( :TERM + 1 ) :NR
END

TO LOG :NUM
; [Natural logarithm general case]
; [( PRINT "LOG :NUM]
IF NOT ( :NUM > 0 ) [OP :NUM / 0]
IF :NUM = 1 [OUTPUT 0]
IF :NUM < 1 [OP - LOG ( 1 / :NUM )]
IF :NUM < 1.7 [OP LOG1P :NUM - 1]
OUTPUT 2 * LOG SQR :NUM
END

TO LOG1P :NUM
; [LOG ( 1 + :NUM ) for :NUM close to 0]
( PRINT "LOG1P :NUM
; [OUTPUT LOG1P.1 :NUM :NUM 1 0]
OUTPUT :NUM + LOG1P.1 :NUM ( - SQ :NUM ) 2 0
END

TO LOG1P.1 :X :NUMER :DENOM :RESULT
OUTPUT LOG1P.2 :X :NUMER :DENOM :RESULT :RESULT + ( :NUMER / :DENOM )
END

TO LOG1P.2 :X :NUMER :DENOM :RESULT :NR
; [( PRINT "LOG1P.2 :X :NUMER :DENOM :RESULT :NR]
IF :NR = :RESULT [OUTPUT :RESULT]
OP LOG1P.1 :X ( - :NUMER * :X ) ( :DENOM + 1 ) :NR
END

TO MIN :NUM1 :NUM2
OUTPUT ( IF :NUM1 < :NUM2 [:NUM1] [:NUM2] )
END

TO POW :X :Y
; [:X ^ :Y or :X * * :Y general case]
( PRINT "POW :X :Y
; [IF :Y = 0 [OUTPUT 1]]
; [IF :Y = 1 [OUTPUT :X]]
; [IF :X = 0 [OUTPUT 0]]
IF :Y < 0 [OP 1 / POW :X ( - :Y )]
IF :Y = INT :Y [OUTPUT POW.1 :X :Y]
IF :Y < 1 [OP EXP ( :Y * LOG :X )]
OP ( POW :X INT :Y ) * POW :X ( :Y - INT :Y )
END

TO POW.1 :X :Y
( PRINT "POW.1 :X :Y
IF :Y = 0 [OUTPUT 1]
IF 1 = REMAINDER :Y 2 [OP :X * POW.1 :X ( :Y - 1 )]
OUTPUT POW.1 SQ :X ( :Y / 2 )
END

TO SQ :NUM
OUTPUT :NUM * :NUM
END

TO SQR :NUM
; [Slightly more accurate SQRT]
; [Yes I cheat for large :NUM]
( PRINT "SQR :NUM
IF :NUM < 0 [OUTPUT SQRT :NUM]
IF :NUM = 0 [OUTPUT 0]
IF :NUM = 1 [OUTPUT 1]
IF :NUM < 1 [OP SQR.1 :NUM :NUM 1]
IF :NUM < 2 [OP SQR.1 :NUM 1 1.415]
OP SQR.1 :NUM 0.9 * SQRT :NUM MIN 1.1 * SQRT :NUM 1.0E+49
END

TO SQR.1 :TARG :LO :HI
; [( PRINT "SQR.1 :TARG :LO :HI]
OUTPUT SQR.2 :TARG :LO :HI ( :LO + :HI ) / 2
END

TO SQR.2 :TARG :LO :HI :GUESS
; [( PRINT "SQR.2 :TARG :LO :HI :GUESS]
IF NOT AND ( :LO < :GUESS ) ( :GUESS < :HI ) [OUTPUT :GUESS]
OUTPUT SQR.3 :TARG :LO :HI :GUESS :GUESS * :GUESS
END

TO SQR.3 :TARG :LO :HI :GUESS :GR
IF :GR = :TARG [OUTPUT :GUESS]
OP SQR.1 :TARG ( IF :GR < :TARG [:GUESS] [:LO] ) ( IF :GR < :TARG [:HI] [:GUESS] )
END

 

Link to comment
Share on other sites

On 12/20/2022 at 6:16 PM, Mariano DM said:

Hey @ascrnet. Do you have the Spanish rom dump for logo ? I only got the English one. And I startd at 12 with that one.

 

I used to have the manuals and cart, but all was lost when moved out.

sorry for the delay, but better late than never. here is everything.😉

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

  • 1 month later...

Hey, has anyone worked with multiple turtles using the ASK, EACH, TELL, and WHO commands? I gave it a shot over the weekend. And you thought just one turtle was slow 😂

 

EACH seems to play well with ASK, but if you duplicate a turtle number in ASK or TELL, like TELL [ 1 2 3 2 ] very strange things happen! Also, if you're talking to multiple turtles and call a function like HEADING or POS outside of EACH, you get a result, but for which turtle?

 

Here's an example of working with all 4 turtles but without shenanigans,

 

TO DRIVER
CS
FS
TELL [0 1 2 3]
PU BACK 75 LEFT 90 FORWARD 75
' [Turtle 0 stays put,]
' [Turtle 1 advances once,]
' [2 twice, etc.]
EACH [REPEAT WHO [RIGHT 90 FD 150]]
PD
' [All turtles go simultaneously]
SETPN 0 RT 90 HILLS 150 10
' [All turtles go one at a time]
SETPN 1 EACH [RT 90 HILLS 150 10]
' [Only turtle 0 goes all around]
SETPN 2 ASK 0 [REPEAT 4 [RT 90 HILLS 150 10]]
WAIT 600
SS
PRINT "OK
END

TO HILLS :DIST :MD
IF :DIST < :MD [FORWARD :DIST STOP]
HILLS.1 :DIST :DIST / 3 :MD
END

TO HILLS.1 :DIST :D3 :MD
HILLS :D3 :MD
LEFT 60
HILLS :D3 :MD
RIGHT 120
HILLS :D3 :MD
LEFT 60
HILLS :D3 :MD
END

TO ' :COMMENT
END

Turtles1.thumb.png.9a864094ed839383178a882e1051bda7.pngTurtles2.png.4d3356c226d518662f932cdddb0940b3.png

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Here's an attempt to use the custom turtle shapes to do some simple animation. I use the "dynamic" features WHEN and SETSP for sound and moving the turtles while the main program switches the turtles' shapes. This led to some funny interactions when I used the same variable names in procedures called from the driver and in a procedure called from a WHEN "daemon." There also seem to be other oddities with local vs. global variables that I'm still looking into. The turtles don't always stay in lockstep even though they all start from the same vertical coordinate and all have the same speed, so I have to line them back up with that SETY in WHEN7.1. They still never wind up in the same place at the end 🤷‍♂️

 

TO DRIVER
CS
TELL [0 1 2 3]
SETSP 0
HT
PU
BACK 58
RIGHT 90
BACK 32
EACH [FORWARD ( WHO * 16]
LEFT 90
LOADSH "LAUNCH
EACH [SETSH ( WHO + 1]
ST
MAKE "FREQ 14
WHEN 7 [WHEN7]
DRIVE 60
LOADSH "FLIGHT
SETSP 1
REPEAT 65 [DRIVE 6]
SETSP 0
WHEN 7 []
PRINT "OK
END

TO ' :COMMENT
END

TO DRIVE :W
WAIT :W EACH [SETSH ( WHO + 1]
WAIT :W EACH [SETSH ( WHO + 5]
WAIT :W EACH [SETSH ( WHO + 9]
END

TO LOADSH :NAME
' [Load all Turtle shapes from variable]
LOADSH.1 1 THING :NAME
END

TO LOADSH.1 :SN :SHAPES
IF :SN = 16 [STOP]
PUTSH :SN FIRST :SHAPES
LOADSH.1 :SN + 1 BUTFIRST :SHAPES
END

TO SAVESH :NAME
' [Save all Turtle shapes to variable]
MAKE :NAME SAVESH.1 1
END

TO SAVESH.1 :SN
IF :SN = 16 [OUTPUT []]
OP FPUT GETSH :SN SAVESH.1 ( :SN + 1 )
END

TO WHEN7
WHEN7.1 THING "FREQ
MAKE "FREQ ( 2 + THING "FREQ
END

TO WHEN7.1 :FREQ
SETY FIRST BUTFIRST POS
SETSP SPEED * 1.1
TOOT 1 1 + :FREQ 10 80
TOOT 0 :FREQ 10 80
END


MAKE "FLIGHT [[0 0 0 0 7 24 96 182 96 24 7 0 0 0 0 0] [7 24 32 255 0 0 0 219 0 0 0 255 4 3 0 0] [224 24 4 255 0 0 0 109 0 0 0 255 32 192 0 0] [0 0 0 0 224 24 6 181 6 24 224 0 0 0 0 0] [0 0 0 0 7 24 96 155 96 24 7 0 0 0 0 0] [7 24 32 255 0 0 0 109 0 0 0 255 4 3 0 0] [224 24 4 255 0 0 0 182 0 0 0 255 32 192 0 0] [0 0 0 0 224 24 6 217 6 24 224 0 0 0 0 0] [0 0 0 0 7 24 96 173 96 24 7 0 0 0 0 0] [7 24 32 255 0 0 0 182 0 0 0 255 4 3 0 0] [224 24 4 255 0 0 0 219 0 0 0 255 32 192 0 0] [0 0 0 0 224 24 6 109 6 24 224 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]
MAKE "FREQ 102
MAKE "LAUNCH [[0 0 0 0 7 24 96 182 96 24 7 0 0 0 0 0] [7 24 32 255 0 0 0 219 0 0 0 255 29 51 97 195] [224 24 4 255 0 0 0 109 0 0 0 255 184 204 134 195] [0 0 0 0 224 24 6 181 6 24 224 0 0 0 0 0] [0 0 0 0 7 24 96 182 96 24 7 0 0 0 0 0] [7 24 32 255 0 0 0 219 0 0 0 255 61 115 227 0] [224 24 4 255 0 0 0 109 0 0 0 255 188 206 199 0] [0 0 0 0 224 24 6 181 6 24 224 0 0 0 0 0] [0 0 0 0 7 24 96 182 96 24 7 0 0 0 0 0] [7 24 32 255 0 0 0 219 0 0 0 255 255 227 0 0] [224 24 4 255 0 0 0 109 0 0 0 255 255 199 0 0] [0 0 0 0 224 24 6 181 6 24 224 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]

 

S2.png

S3.png

S0.png

S1.png

Link to comment
Share on other sites

6 hours ago, ascrnet said:

 

Hi @yetanothertroll

 

I recommend a good logo book rather than making geometric figures, this one contains several games. 😉

 

greetings

Thanks, this has some good stuff! Unfortunately, the scan cuts off at page 361/377, leaving out the appendix and index. The final "lines and mirrors" program appears to be complete at least. I've actually been noodling around with a program similar to "lines and mirrors" but more oriented to having all four turtles bouncing off the walls as well as each other, but I got sidetracked by finding out I had completely misunderstood how MAKE, NAMEP, and THING worked and how variables worked in general. Page 16 of the Atari Logo Reference Manual (around pg 22 in scanned PDFs) was an eye opener. I thought MAKE, NAMEP, and THING only worked with global variables and that the parameters in procedures were immutable and could only be accessed with :FOO :BAR and the like. Whoops. So, FFOR1 and FFOR2 work the same, but for some reason FFOR2 starts thrashing the garbage collector when the nodes start running low where FFOR1 doesn't as well as being just plain ugly:

 

TO FFOR1 :N
OUTPUT FFOR1.1 :N []
END

TO FFOR1.1 :N :R
IF :N < 1 [OUTPUT :R]
OP FFOR1.1 :N - 1 FPUT :N :R
END

TO FFOR2 :N
OUTPUT FFOR2.1 []
END

TO FFOR2.1 :R
FFOR2.2
OUTPUT :R
END

TO FFOR2.2
IF :N < 1 [STOP]
MAKE "R FPUT :N :R
MAKE "N :N - 1
FFOR2.2
END

 

TL;DR: This works, but for the record, I really really really don't like the idea of using MAKE in this way.

Link to comment
Share on other sites

On 10/28/2023 at 3:08 PM, ascrnet said:

 

Hi @yetanothertroll

 

I recommend a good logo book rather than making geometric figures, this one contains several games. 😉

 

greetings

I noticed one of the authors of that book is Brian Harvey.

 

He created UCBLogo an open source version of Logo for modern systems. He also wrote the Computer Science Logo Style books which are a great examples of the stuff Logo can do.

  • Like 3
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...