The program starts at the center of the screen and starts drawing a line in 50ms steps. When the line hits the edge of the terminal it will be reflected and continue drawing. steps takes the number of drawing steps to perform before finishing while until-key finishes on a key press.
Apart from the lack of comments, what would I need to do to make this "good" Forth and how would I change it to fit in one screen (16 lines of 64 chars)?
variable h variable w : height h @ ; : width w @ ; variable point-var cell allot : point ( offset -- addr ) cells point-var + ; variable direction-var cell allot : dir ( offset -- addr ) cells direction-var + ; : init ( -- ) rows h ! cols w ! width 2 / 0 point ! height 2 / 1 point ! 1 0 dir ! 1 1 dir ! ; : reflect-top ( -- t/f ) 1 point @ 0= dup if 1 1 dir ! then invert ; : reflect-bot ( -- t/f ) 1 point @ height 1 - = if -1 1 dir ! then ; : reflect-left ( -- t/f ) 0 point @ width 1 - = if -1 0 dir ! then ; : reflect-right ( -- t/f ) 0 point @ 0= dup if 1 0 dir ! then invert ; : reflect ( -- ) reflect-top if reflect-bot then reflect-right if reflect-left then ; : draw-point ( -- ) [char] # emit ; : move-x ( -- n ) 0 point @ 0 dir @ + dup 0 point ! ; : move-y ( -- n ) 1 point @ 1 dir @ + dup 1 point ! ; : move-xy ( -- ) move-x move-y at-xy ; : try ; : step ( -- ) try reflect move-xy draw-point ; : steps ( n -- ) init page 0 do step 50 ms loop ; : until-key ( n -- ) init page begin step 50 ms key? until ;
at-xy,invert). \$\endgroup\$invert(used as logical not) andat-xyare provided by gforth in the base dictionary.at-xy ( posX posY -- )just prints the "\x1b[y;xH" escape sequence to move the cursor. \$\endgroup\$